Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full wasm support with wasm-bindgen-futures #445

Merged
merged 53 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
9372e32
Give tungstenite types distinct names
bitfl0wer Nov 19, 2023
73e40ca
reorganize files
bitfl0wer Nov 19, 2023
ec38130
Better feature locking, add wasm.rs
bitfl0wer Nov 19, 2023
984fdac
Implement wasm Backend
bitfl0wer Nov 19, 2023
dc0c2ee
add wasm-bindgen-test
bitfl0wer Nov 19, 2023
1bcf54c
Build & Test for wasm
bitfl0wer Nov 19, 2023
d0bc0bb
Add macos safari wasm test
bitfl0wer Nov 19, 2023
ced6496
Add wasm32 target
bitfl0wer Nov 19, 2023
2690819
Add wasm.rs test
bitfl0wer Nov 19, 2023
ce9c1d5
Move wasm-pack installation before test execution
bitfl0wer Nov 19, 2023
81091eb
Fix build on wasm32
bitfl0wer Nov 19, 2023
0782f25
Fix examples depending on tokio::time
bitfl0wer Nov 19, 2023
2543427
fix clippy warn
bitfl0wer Nov 19, 2023
3e2152d
Merge branch 'dev' into feature/wasm32-unknown
bitfl0wer Nov 19, 2023
a811031
Add example wasm bindgen test
bitfl0wer Nov 19, 2023
c456d65
Add wasm-bindgen to Cargo.toml
bitfl0wer Nov 20, 2023
62e9123
Add wasm test configuration
bitfl0wer Nov 20, 2023
c9d4ecd
Install wasm-bindgen-cli on linux
bitfl0wer Nov 20, 2023
7f94b8e
Add wasm-bindgen-cli to macos
bitfl0wer Nov 20, 2023
a52dd1e
Correct "vers" to "version"
bitfl0wer Nov 20, 2023
401249b
Attempt to locate correct geckodriver
bitfl0wer Nov 20, 2023
a2834b2
Run wasm tests first
bitfl0wer Nov 20, 2023
083f438
maybe this will fix ci :clueless:
bitfl0wer Nov 20, 2023
7862c5f
Move wasm-bindgen-cli install
bitfl0wer Nov 20, 2023
7e4f60b
Add cargo-binstall installation script for
bitfl0wer Nov 20, 2023
608629a
Try using only one browser
bitfl0wer Nov 20, 2023
c492f85
remove geckodriver
bitfl0wer Nov 20, 2023
79d97a1
Move all wasm related tests to macos
bitfl0wer Nov 20, 2023
31136ad
Rename macOS test step for clarity
bitfl0wer Nov 20, 2023
584fd21
Try out combined coverage report
bitfl0wer Nov 20, 2023
cae64ae
try different strategy to skip coverage on forks
bitfl0wer Nov 20, 2023
06574c2
Revert "try different strategy to skip coverage on forks"
bitfl0wer Nov 20, 2023
5e20d77
Revert "Try out combined coverage report"
bitfl0wer Nov 20, 2023
4288455
Add tests for WASM
bitfl0wer Nov 20, 2023
c985882
Merge branch 'dev' into feature/wasm32-unknown
bitfl0wer Nov 20, 2023
8eee0c8
remove all .await from wasm tests
bitfl0wer Nov 20, 2023
ebb414c
Remove unnecessary code
bitfl0wer Nov 20, 2023
42d512e
Rename test function to
bitfl0wer Nov 20, 2023
0acf3fb
Fix formatting in test functions
bitfl0wer Nov 20, 2023
325c3d3
Spawn local gateway task on wasm32
bitfl0wer Nov 20, 2023
f0a4fe6
Refactor heartbeat task to support WebAssembly
bitfl0wer Nov 20, 2023
0ff0244
Revert "Refactor heartbeat task to support WebAssembly"
bitfl0wer Nov 20, 2023
1ad93e2
Revert "Spawn local gateway task on wasm32"
bitfl0wer Nov 20, 2023
9ddf8dd
Add FIXME comments for wasm compatibility
bitfl0wer Nov 21, 2023
e6417d8
Add build instructions, especially for wasm
bitfl0wer Nov 22, 2023
f63881d
Remove 'handle', add wasm friendly task spawning
bitfl0wer Nov 22, 2023
233a89c
add wasm friendly task spawning
bitfl0wer Nov 22, 2023
1c7e318
Add wasm-bindgen-futures
bitfl0wer Nov 22, 2023
383f1ca
Remove broken test code
bitfl0wer Nov 22, 2023
8bf2801
Replace #[tokio::test] w/ wasm-ok macro calls
bitfl0wer Nov 22, 2023
6041947
Add fixme note about tests requiring std::fs
bitfl0wer Nov 22, 2023
889db10
Update supported platforms in README
bitfl0wer Nov 22, 2023
14bbeb3
Split up wasm-tests into 3 seperate tests
bitfl0wer Nov 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
cargo build --verbose --all-features
cargo test --verbose --all-features
fi
macos:
wasm-safari:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -73,5 +73,59 @@ jobs:
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall --no-confirm wasm-bindgen-cli --version "0.2.88" --force
SAFARIDRIVER=$(which safaridriver) cargo test --target wasm32-unknown-unknown --no-default-features --features="client, rt"
wasm-gecko:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Clone spacebar server
run: |
git clone https://github.com/bitfl0wer/server.git
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
cache-dependency-path: server/package-lock.json
- name: Prepare and start Spacebar server
run: |
npm install
npm run setup
npm run start &
working-directory: ./server
- uses: Swatinem/rust-cache@v2
with:
cache-all-crates: "true"
prefix-key: "macos"
- name: Run WASM tests with Safari, Firefox, Chrome
run: |
rustup target add wasm32-unknown-unknown
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall --no-confirm wasm-bindgen-cli --version "0.2.88" --force
GECKODRIVER=$(which geckodriver) cargo test --target wasm32-unknown-unknown --no-default-features --features="client, rt"
wasm-chrome:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Clone spacebar server
run: |
git clone https://github.com/bitfl0wer/server.git
- uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
cache-dependency-path: server/package-lock.json
- name: Prepare and start Spacebar server
run: |
npm install
npm run setup
npm run start &
working-directory: ./server
- uses: Swatinem/rust-cache@v2
with:
cache-all-crates: "true"
prefix-key: "macos"
- name: Run WASM tests with Safari, Firefox, Chrome
run: |
rustup target add wasm32-unknown-unknown
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
cargo binstall --no-confirm wasm-bindgen-cli --version "0.2.88" --force
CHROMEDRIVER=$(which chromedriver) cargo test --target wasm32-unknown-unknown --no-default-features --features="client, rt"
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ hostname = "0.3.1"
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2.11", features = ["js"] }
ws_stream_wasm = "0.7.4"

wasm-bindgen-futures = "0.4.38"

[dev-dependencies]
lazy_static = "1.4.0"
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ dbg!(&user.object.read().unwrap().username);
## Supported Platforms

All major desktop operating systems (Windows, macOS (aarch64/x86_64), Linux (aarch64/x86_64)) are supported.
We are currently working on adding full support for `wasm32-unknown-unknown`. This will allow you to use Chorus in
`wasm32-unknown-unknown` is a supported compilation target on versions `>0.11.0`. This allows you to use Chorus in
your browser, or in any other environment that supports WebAssembly.

We recommend checking out the examples directory, as well as the documentation for more information.
Expand All @@ -107,6 +107,25 @@ We recommend checking out the examples directory, as well as the documentation f

Rust **1.67.1**. This number might change at any point while Chorus is not yet at version 1.0.0.

## Development Setup

Make sure that you have at least Rust 1.67.1 installed. You can check your Rust version by running `cargo --version`
in your terminal. To compile for `wasm32-unknown-unknown`, you need to install the `wasm32-unknown-unknown` target.
You can do this by running `rustup target add wasm32-unknown-unknown`.

### Testing

In general, the tests will require you to run a local instance of the Spacebar server. You can find instructions on how
to do that [here](https://docs.spacebar.chat/setup/server/). You can find a pre-configured version of the server
[here](https://github.com/bitfl0wer/server). It is recommended to use the pre-configured version, as certain things
like "proxy connection checking" are already disabled on this version, which otherwise might break tests.

### wasm

To test for wasm, you will need to `cargo install wasm-pack`. You can then run
`wasm-pack test --<chrome/firefox/safari> --headless -- --target wasm32-unknown-unknown --features="rt, client" --no-default-features`
to run the tests for wasm.

## Versioning

This crate uses Semantic Versioning 2.0.0 as its versioning scheme. You can read the specification [here](https://semver.org/spec/v2.0.0.html).
Expand Down
6 changes: 6 additions & 0 deletions src/gateway/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::time::Duration;

use futures_util::{SinkExt, StreamExt};
use log::*;
#[cfg(not(target_arch = "wasm32"))]
use tokio::task;

use self::event::Events;
Expand Down Expand Up @@ -74,9 +75,14 @@ impl Gateway {
};

// Now we can continuously check for messages in a different task, since we aren't going to receive another hello
#[cfg(not(target_arch = "wasm32"))]
task::spawn(async move {
gateway.gateway_listen_task().await;
});
#[cfg(target_arch = "wasm32")]
wasm_bindgen_futures::spawn_local(async move {
gateway.gateway_listen_task().await;
});

Ok(GatewayHandle {
url: websocket_url.clone(),
Expand Down
13 changes: 8 additions & 5 deletions src/gateway/heartbeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use std::time::{self, Duration, Instant};
use tokio::sync::mpsc::{Receiver, Sender};

use safina_timer::sleep_until;
use tokio::task::{self, JoinHandle};
#[cfg(not(target_arch = "wasm32"))]
use tokio::task;

use super::*;
use crate::types;
Expand All @@ -20,8 +21,6 @@ pub(super) struct HeartbeatHandler {
pub heartbeat_interval: Duration,
/// The send channel for the heartbeat thread
pub send: Sender<HeartbeatThreadCommunication>,
/// The handle of the thread
handle: JoinHandle<()>,
}

impl HeartbeatHandler {
Expand All @@ -33,14 +32,18 @@ impl HeartbeatHandler {
let (send, receive) = tokio::sync::mpsc::channel(32);
let kill_receive = kill_rc.resubscribe();

let handle: JoinHandle<()> = task::spawn(async move {
#[cfg(not(target_arch = "wasm32"))]
task::spawn(async move {
Self::heartbeat_task(websocket_tx, heartbeat_interval, receive, kill_receive).await;
});
#[cfg(target_arch = "wasm32")]
wasm_bindgen_futures::spawn_local(async move {
Self::heartbeat_task(websocket_tx, heartbeat_interval, receive, kill_receive).await;
});

Self {
heartbeat_interval,
send,
handle,
}
}

Expand Down
8 changes: 7 additions & 1 deletion tests/auth.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
use chorus::types::RegisterSchema;
// PRETTYFYME: Move common wasm setup to common.rs
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);

mod common;

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn test_registration() {
let bundle = common::setup().await;
let reg = RegisterSchema {
Expand Down
21 changes: 16 additions & 5 deletions tests/channels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ use chorus::types::{
};

mod common;
// PRETTYFYME: Move common wasm setup to common.rs

#[tokio::test]
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn get_channel() {
let mut bundle = common::setup().await;
let bundle_channel = bundle.channel.read().unwrap().clone();
Expand All @@ -18,7 +25,8 @@ async fn get_channel() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn delete_channel() {
let mut bundle = common::setup().await;
let channel_guard = bundle.channel.write().unwrap().clone();
Expand All @@ -27,7 +35,8 @@ async fn delete_channel() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn modify_channel() {
const CHANNEL_NAME: &str = "beepboop";
let mut bundle = common::setup().await;
Expand Down Expand Up @@ -85,7 +94,8 @@ async fn modify_channel() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn get_channel_messages() {
let mut bundle = common::setup().await;
let channel_id: Snowflake = bundle.channel.read().unwrap().id;
Expand Down Expand Up @@ -141,7 +151,8 @@ async fn get_channel_messages() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn create_dm() {
let mut bundle = common::setup().await;
let other_user = bundle.create_user("integrationtestuser2").await;
Expand Down
17 changes: 13 additions & 4 deletions tests/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ use std::sync::{Arc, RwLock};

use chorus::gateway::*;
use chorus::types::{self, ChannelModifySchema, RoleCreateModifySchema, RoleObject};
// PRETTYFYME: Move common wasm setup to common.rs
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
/// Tests establishing a connection (hello and heartbeats) on the local gateway;
async fn test_gateway_establish() {
let bundle = common::setup().await;
Expand All @@ -14,7 +20,8 @@ async fn test_gateway_establish() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
/// Tests establishing a connection and authenticating
async fn test_gateway_authenticate() {
let bundle = common::setup().await;
Expand All @@ -28,7 +35,8 @@ async fn test_gateway_authenticate() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn test_self_updating_structs() {
let mut bundle = common::setup().await;
let received_channel = bundle
Expand Down Expand Up @@ -61,7 +69,8 @@ async fn test_self_updating_structs() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn test_recursive_self_updating_structs() {
// Setup
let mut bundle = common::setup().await;
Expand Down
20 changes: 15 additions & 5 deletions tests/guilds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ use chorus::types::{
};

mod common;
// PRETTYFYME: Move common wasm setup to common.rs
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn guild_creation_deletion() {
let mut bundle = common::setup().await;

Expand All @@ -26,15 +32,17 @@ async fn guild_creation_deletion() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn get_channels() {
let mut bundle = common::setup().await;
let guild = bundle.guild.read().unwrap().clone();
println!("{:?}", guild.channels(&mut bundle.user).await.unwrap());
common::teardown(bundle).await;
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn guild_create_ban() {
// TODO: When routes exist to check if user x is on guild y, add this as an assertion to check
// if Spacebar actually bans the user.
Expand Down Expand Up @@ -71,7 +79,8 @@ async fn guild_create_ban() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn modify_guild() {
let mut bundle = common::setup().await;
let schema = GuildModifySchema {
Expand All @@ -86,7 +95,8 @@ async fn modify_guild() {
common::teardown(bundle).await
}

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn guild_remove_member() {
let mut bundle = common::setup().await;
let channel = bundle.channel.read().unwrap().clone();
Expand Down
8 changes: 7 additions & 1 deletion tests/instance.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
mod common;
// PRETTYFYME: Move common wasm setup to common.rs
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);

#[tokio::test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn generate_general_configuration_schema() {
let bundle = common::setup().await;
bundle
Expand Down
9 changes: 8 additions & 1 deletion tests/invites.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
mod common;
use chorus::types::CreateChannelInviteSchema;
#[tokio::test]
// PRETTYFYME: Move common wasm setup to common.rs
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
async fn create_accept_invite() {
let mut bundle = common::setup().await;
let channel = bundle.channel.read().unwrap().clone();
Expand Down
Loading
Loading