From 2f54bb638164faaebf1150e81abb2786924b692e Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Sat, 24 Feb 2024 20:50:00 -0800 Subject: [PATCH] feat: add wasm testing (#63) --- riven/Cargo.toml | 20 ++++++++++++++--- riven/examples/proxy/main.rs | 2 -- riven/tests/test_ru.rs | 2 +- riven/tests/tests_americas.rs | 8 +++---- riven/tests/tests_asia_jp.rs | 18 +++++++-------- riven/tests/tests_europe.rs | 4 ++-- riven/tests/tests_euw.rs | 6 ++--- riven/tests/tests_euw_tft.rs | 14 ++++++------ riven/tests/tests_la1.rs | 8 +++---- riven/tests/tests_na.rs | 16 +++++++------- riven/tests/tests_ph2.rs | 2 +- riven/tests/tests_sg2.rs | 2 +- riven/tests/tests_th2.rs | 2 +- riven/tests/tests_tr.rs | 38 +++++++++++++++----------------- riven/tests/tests_val_latam.rs | 4 ++-- riven/tests/tests_vn2.rs | 2 +- riven/tests/testutils.rs | 40 +++++++++++++++++++++++++++++++--- 17 files changed, 115 insertions(+), 73 deletions(-) diff --git a/riven/Cargo.toml b/riven/Cargo.toml index 782b68d..68e7579 100644 --- a/riven/Cargo.toml +++ b/riven/Cargo.toml @@ -36,6 +36,12 @@ deny-unknown-enum-variants = [ "deny-unknown-enum-variants-strings", "deny-unkno deny-unknown-enum-variants-strings = [] deny-unknown-enum-variants-integers = [] +__proxy = [] + +[[example]] +name = "proxy" +required-features = [ "__proxy" ] + [dependencies] futures = "0.3" log = "0.4" @@ -60,8 +66,16 @@ web-time = "1.0.0" [dev-dependencies] env_logger = "0.10.0" fake_instant = "0.5.0" -hyper = { version = "0.14", features = [ "server" ] } -tokio = { version = "1", features = [ "full" ] } -tokio-shared-rt = "0.1" tracing = "0.1" tracing-subscriber = "0.2" + +[target.'cfg(not(target_family = "wasm"))'.dev-dependencies] +hyper = { version = "0.14", features = [ "server" ] } +tokio = { version = "1", features = [ "macros", "rt-multi-thread" ] } +tokio-shared-rt = "0.1" + +[target.'cfg(target_family = "wasm")'.dev-dependencies] +console_error_panic_hook = "0.1" +console_log = "1.0" +wasm-bindgen = "0.2" +wasm-bindgen-test = "0.3" diff --git a/riven/examples/proxy/main.rs b/riven/examples/proxy/main.rs index 8b7513b..9b114ac 100644 --- a/riven/examples/proxy/main.rs +++ b/riven/examples/proxy/main.rs @@ -1,5 +1,3 @@ -// #![deny(warnings)] - use std::convert::Infallible; use std::sync::OnceLock; diff --git a/riven/tests/test_ru.rs b/riven/tests/test_ru.rs index 911b4e3..ef6b7b0 100644 --- a/riven/tests/test_ru.rs +++ b/riven/tests/test_ru.rs @@ -4,7 +4,7 @@ use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::RU; -#[tokio_shared_rt::test] +#[riven_test] async fn summoner_leagues() -> Result<(), String> { let sum = riot_api() .summoner_v4() diff --git a/riven/tests/tests_americas.rs b/riven/tests/tests_americas.rs index 32e8e9b..993a1f2 100644 --- a/riven/tests/tests_americas.rs +++ b/riven/tests/tests_americas.rs @@ -11,7 +11,7 @@ static MATCHES: &[&str] = &[ ]; /// Account-v1 -#[tokio_shared_rt::test] +#[riven_test] async fn account_v1_getbyriotid_getbypuuid() -> Result<(), String> { // Game name is case and whitespace insensitive. // But tag cannot have spaces. (Is it case sensitive?). @@ -34,7 +34,7 @@ async fn account_v1_getbyriotid_getbypuuid() -> Result<(), String> { } /// Tournament stub test. -#[tokio_shared_rt::test] +#[riven_test] async fn tournamentstub() -> Result<(), String> { let ts = riot_api().tournament_stub_v5(); let provider_id = ts @@ -95,12 +95,12 @@ async fn tournamentstub() -> Result<(), String> { } } -#[tokio_shared_rt::test] +#[riven_test] async fn match_v5_get_test() -> Result<(), String> { match_v5_get(ROUTE, MATCHES).await } -#[tokio_shared_rt::test] +#[riven_test] async fn match_v5_get_timeline_test() -> Result<(), String> { match_v5_get_timeline(ROUTE, MATCHES).await } diff --git a/riven/tests/tests_asia_jp.rs b/riven/tests/tests_asia_jp.rs index 36321d8..2514dd5 100644 --- a/riven/tests/tests_asia_jp.rs +++ b/riven/tests/tests_asia_jp.rs @@ -23,7 +23,7 @@ static MATCHES: &[&str] = &[ ]; /// Summoner tests. -#[tokio_shared_rt::test] +#[riven_test] async fn summoner_get_kanjikana() -> Result<(), String> { let p = riot_api() .summoner_v4() @@ -39,7 +39,7 @@ async fn summoner_get_kanjikana() -> Result<(), String> { // Failure cases. // /// Make sure get_raw_response(...) with invalid path fails as expected. -// #[tokio_shared_rt::test] +// #[riven_test] // async fn raw_response_invalid -> Result<(), String> { // let p = riot_api().get_raw_response("summoner-v4.getBySummonerName", Region::JP.into(), "INVALID/PATH".to_owned(), None); // let r = p.await; @@ -49,7 +49,7 @@ async fn summoner_get_kanjikana() -> Result<(), String> { /// summoner_v4().get_by_summoner_name(...) normally returns an option. /// If we use `get` (instead of `get_optional`) make sure it errors. -#[tokio_shared_rt::test] +#[riven_test] async fn get_nonoptional_invalid() -> Result<(), String> { let path_string = format!( "/lol/summoner/v4/summoners/by-name/{}", @@ -67,7 +67,7 @@ async fn get_nonoptional_invalid() -> Result<(), String> { } /// Check invalid code, make sure 403 is handled as expected. -#[tokio_shared_rt::test] +#[riven_test] async fn tournament_forbidden() -> Result<(), String> { let p = riot_api() .tournament_v5() @@ -84,7 +84,7 @@ async fn tournament_forbidden() -> Result<(), String> { // Disabled: Caihonbbt no longer ranked. // /// tft-league-v1.getLeagueEntriesForSummoner // /// https://github.com/MingweiSamuel/Riven/issues/25 -// #[tokio_shared_rt::test] +// #[riven_test] // async fn tft_league_getleagueentriesforsummoner() -> Result<(), String> { // let sp = riot_api().summoner_v4().get_by_summoner_name(ROUTE, "Caihonbbt"); // let sr = sp.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to get \"Caihonbbt\"".to_owned())?; @@ -96,7 +96,7 @@ async fn tournament_forbidden() -> Result<(), String> { /// tft-league-v1.getTopRatedLadder /// https://github.com/MingweiSamuel/Riven/issues/24 -#[tokio_shared_rt::test] +#[riven_test] async fn tft_league_gettopratedladder() -> Result<(), String> { let lp = riot_api() .tft_league_v1() @@ -107,17 +107,17 @@ async fn tft_league_gettopratedladder() -> Result<(), String> { } /// ASIA regional tests -#[tokio_shared_rt::test] +#[riven_test] async fn league_v4_match_v5_latest_combo_test() -> Result<(), String> { league_v4_match_v5_latest_combo(ROUTE).await } -#[tokio_shared_rt::test] +#[riven_test] async fn match_v5_get_test() -> Result<(), String> { match_v5_get(ROUTE.to_regional(), MATCHES).await } -#[tokio_shared_rt::test] +#[riven_test] async fn match_v5_get_timeline_test() -> Result<(), String> { match_v5_get_timeline(ROUTE.to_regional(), MATCHES).await } diff --git a/riven/tests/tests_europe.rs b/riven/tests/tests_europe.rs index b969af6..974bc14 100644 --- a/riven/tests/tests_europe.rs +++ b/riven/tests/tests_europe.rs @@ -22,12 +22,12 @@ static MATCHES: &[&str] = &[ "EUW1_6568537080", ]; -#[tokio_shared_rt::test] +#[riven_test] async fn match_v5_get_test() -> Result<(), String> { match_v5_get(ROUTE, MATCHES).await } -#[tokio_shared_rt::test] +#[riven_test] async fn match_v5_get_timeline_test() -> Result<(), String> { match_v5_get_timeline(ROUTE, MATCHES).await } diff --git a/riven/tests/tests_euw.rs b/riven/tests/tests_euw.rs index a7a36a1..34e7b96 100644 --- a/riven/tests/tests_euw.rs +++ b/riven/tests/tests_euw.rs @@ -6,7 +6,7 @@ const ROUTE: PlatformRoute = PlatformRoute::EUW1; // Champion Mastery tests -#[tokio_shared_rt::test] +#[riven_test] async fn championmastery_getscore_ma5tery() -> Result<(), String> { let sum = riot_api() .summoner_v4() @@ -30,7 +30,7 @@ async fn championmastery_getscore_ma5tery() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn championmastery_getall_ma5tery() -> Result<(), String> { let sum = riot_api() .summoner_v4() @@ -51,7 +51,7 @@ async fn championmastery_getall_ma5tery() -> Result<(), String> { } /// https://github.com/RiotGames/developer-relations/issues/602 -#[tokio_shared_rt::test] +#[riven_test] async fn spectator_combo() -> Result<(), String> { let featured_p = riot_api().spectator_v4().get_featured_games(ROUTE); let featured = featured_p.await.map_err(|e| e.to_string())?; diff --git a/riven/tests/tests_euw_tft.rs b/riven/tests/tests_euw_tft.rs index 26e551e..0b09f09 100644 --- a/riven/tests/tests_euw_tft.rs +++ b/riven/tests/tests_euw_tft.rs @@ -14,20 +14,20 @@ static TFT_MATCHES: &[&str] = &[ "EUW1_6807630149", ]; -#[tokio_shared_rt::test] +#[riven_test] async fn tftmatchv1_get_list() -> Result<(), String> { tft_match_v1_get(ROUTE.to_regional(), TFT_MATCHES).await } // /// Don't have acecess to tft-status-v1. -// #[tokio_shared_rt::test] +// #[riven_test] // async fn tftstatusv1_getplatformdata() -> Result<(), String> { // let p = riot_api().tft_status_v1().get_platform_data(ROUTE); // let _s = p.await.map_err(|e| e.to_string())?; // Ok(()) // } -#[tokio_shared_rt::test] +#[riven_test] async fn tftleaguev1_gettopratedladder() -> Result<(), String> { let p = riot_api() .tft_league_v1() @@ -41,7 +41,7 @@ async fn tftleaguev1_gettopratedladder() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn tftmatchv1_getmatch() -> Result<(), String> { let p = riot_api() .tft_match_v1() @@ -53,7 +53,7 @@ async fn tftmatchv1_getmatch() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn tftsummonerv1_getbyname() -> Result<(), String> { let p = riot_api() .tft_summoner_v1() @@ -65,7 +65,7 @@ async fn tftsummonerv1_getbyname() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn tftsummonerv1_getbyname_none() -> Result<(), String> { let p = riot_api() .tft_summoner_v1() @@ -75,7 +75,7 @@ async fn tftsummonerv1_getbyname_none() -> Result<(), String> { } /// Get top rated player, get some of their matches. -#[tokio_shared_rt::test] +#[riven_test] async fn tft_combo() -> Result<(), String> { let top_players = riot_api() .tft_league_v1() diff --git a/riven/tests/tests_la1.rs b/riven/tests/tests_la1.rs index cf690f8..4badc07 100644 --- a/riven/tests/tests_la1.rs +++ b/riven/tests/tests_la1.rs @@ -1,6 +1,6 @@ mod testutils; use riven::consts::*; -use testutils::riot_api; +use testutils::{riot_api, riven_test}; const ROUTE: PlatformRoute = PlatformRoute::LA1; @@ -9,7 +9,7 @@ const CHALLENGE_ID_ARAM_1K_DPM: i64 = 101101; /// /lol/challenges/v1/challenges/{challengeId}/leaderboards/by-level/{level} /// /lol/challenges/v1/player-data/{puuid} -#[tokio_shared_rt::test] +#[riven_test] async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> { let challenge_id = CHALLENGE_ID_ARAM_1K_DPM; let leaderboard = riot_api() @@ -50,7 +50,7 @@ async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> { /// /lol/challenges/v1/challenges/config /// /lol/challenges/v1/challenges/{challengeId}/config -#[tokio_shared_rt::test] +#[riven_test] async fn lol_challenges_v1_check_configs() -> Result<(), String> { let challenges = riot_api() .lol_challenges_v1() @@ -84,7 +84,7 @@ async fn lol_challenges_v1_check_configs() -> Result<(), String> { /// /lol/challenges/v1/challenges/percentiles /// /lol/challenges/v1/challenges/{challengeId}/percentiles -#[tokio_shared_rt::test] +#[riven_test] async fn lol_challenges_v1_check_percentiles() -> Result<(), String> { // Check all percentiles. let percentiles = riot_api() diff --git a/riven/tests/tests_na.rs b/riven/tests/tests_na.rs index e0dafbe..67ea2f2 100644 --- a/riven/tests/tests_na.rs +++ b/riven/tests/tests_na.rs @@ -19,7 +19,7 @@ const ROUTE: PlatformRoute = PlatformRoute::NA1; // Summoner tests. -#[tokio_shared_rt::test] +#[riven_test] async fn summoner_double() -> Result<(), String> { let l1p = riot_api() .summoner_v4() @@ -39,7 +39,7 @@ async fn summoner_double() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn champion_getrotation() -> Result<(), String> { let p = riot_api().champion_v3().get_champion_info(ROUTE); let d = p.await.map_err(|e| e.to_string())?; @@ -52,7 +52,7 @@ async fn champion_getrotation() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn leagueexp_get() -> Result<(), String> { let p = riot_api().league_exp_v4().get_league_entries( ROUTE, @@ -68,7 +68,7 @@ async fn leagueexp_get() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn champion_mastery_v4() -> Result<(), String> { let summoner = riot_api() .summoner_v4() @@ -87,7 +87,7 @@ async fn champion_mastery_v4() -> Result<(), String> { // Commented out, requires special API key. // /// LOR -// #[tokio_shared_rt::test] +// #[riven_test] // async fn async fn lor_ranked_get_leaderboards() -> Result<(), String> { // let future = riot_api().lor_ranked_v1().get_leaderboards(Region::AMERICAS); // let _leaderboard = future.await.map_err(|e| e.to_string())?; @@ -96,7 +96,7 @@ async fn champion_mastery_v4() -> Result<(), String> { // CLASH -#[tokio_shared_rt::test] +#[riven_test] async fn clash_get_tournaments() -> Result<(), String> { let p = riot_api().clash_v1().get_tournaments(ROUTE); let tours = p.await.map_err(|e| e.to_string())?; @@ -108,7 +108,7 @@ async fn clash_get_tournaments() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn clash_get_team_by_id_invalid() -> Result<(), String> { let p = riot_api() .clash_v1() @@ -118,7 +118,7 @@ async fn clash_get_team_by_id_invalid() -> Result<(), String> { Ok(()) } -#[tokio_shared_rt::test] +#[riven_test] async fn status() -> Result<(), String> { let p = riot_api().lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?; diff --git a/riven/tests/tests_ph2.rs b/riven/tests/tests_ph2.rs index ccf28d7..eeafb63 100644 --- a/riven/tests/tests_ph2.rs +++ b/riven/tests/tests_ph2.rs @@ -4,7 +4,7 @@ use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::PH2; -#[tokio_shared_rt::test] +#[riven_test] async fn status() -> Result<(), String> { let p = riot_api().lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?; diff --git a/riven/tests/tests_sg2.rs b/riven/tests/tests_sg2.rs index aacb82a..0360c5f 100644 --- a/riven/tests/tests_sg2.rs +++ b/riven/tests/tests_sg2.rs @@ -4,7 +4,7 @@ use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::SG2; -#[tokio_shared_rt::test] +#[riven_test] async fn status() -> Result<(), String> { let p = riot_api().lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?; diff --git a/riven/tests/tests_th2.rs b/riven/tests/tests_th2.rs index b74daa1..f974d5d 100644 --- a/riven/tests/tests_th2.rs +++ b/riven/tests/tests_th2.rs @@ -4,7 +4,7 @@ use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::TH2; -#[tokio_shared_rt::test] +#[riven_test] async fn status() -> Result<(), String> { let p = riot_api().lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?; diff --git a/riven/tests/tests_tr.rs b/riven/tests/tests_tr.rs index a7d9076..316cdb3 100644 --- a/riven/tests/tests_tr.rs +++ b/riven/tests/tests_tr.rs @@ -1,37 +1,33 @@ mod testutils; +use futures::future::join_all; use riven::consts::*; use riven::models::summoner_v4::Summoner; -use testutils::riot_api; +use testutils::{riot_api, riven_test}; const ROUTE: PlatformRoute = PlatformRoute::TR1; -#[tokio_shared_rt::test] +#[riven_test] async fn league_summoner_bulk_test() -> Result<(), String> { let p = riot_api() .league_v4() .get_challenger_league(ROUTE, QueueType::RANKED_SOLO_5x5); - // let p = future_start(p); - let ll = p.await.map_err(|e| e.to_string())?; + let league_list = p.await.map_err(|e| e.to_string())?; - println!("{:?} Challenger {} entries.", ROUTE, ll.entries.len()); + println!( + "{:?} Challenger {} entries.", + ROUTE, + league_list.entries.len() + ); - let sl = ll - .entries - .iter() - .take(50) - .map(|entry| { - riot_api() - .summoner_v4() - .get_by_summoner_id(ROUTE, &entry.summoner_id) - }) - .map(tokio::spawn) - .collect::>(); + let summoner_vec = join_all(league_list.entries.iter().take(50).map(|entry| { + riot_api() + .summoner_v4() + .get_by_summoner_id(ROUTE, &entry.summoner_id) + })) + .await; - for (i, s) in sl.into_iter().enumerate() { - let summoner: Summoner = s - .await - .expect("tokio::spawn join error") - .map_err(|e| e.to_string())?; + for (i, s) in summoner_vec.into_iter().enumerate() { + let summoner: Summoner = s.map_err(|e| e.to_string())?; println!("{}: {}", i + 1, summoner.name); } diff --git a/riven/tests/tests_val_latam.rs b/riven/tests/tests_val_latam.rs index a490e41..5209b11 100644 --- a/riven/tests/tests_val_latam.rs +++ b/riven/tests/tests_val_latam.rs @@ -1,10 +1,10 @@ mod testutils; use riven::consts::*; -use testutils::riot_api; +use testutils::{riot_api, riven_test}; const ROUTE: ValPlatformRoute = ValPlatformRoute::LATAM; -#[tokio_shared_rt::test] +#[riven_test] async fn val_content_ranked_test() -> Result<(), String> { let p = riot_api() .val_content_v1() diff --git a/riven/tests/tests_vn2.rs b/riven/tests/tests_vn2.rs index 80150f3..44b6819 100644 --- a/riven/tests/tests_vn2.rs +++ b/riven/tests/tests_vn2.rs @@ -4,7 +4,7 @@ use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::VN2; -#[tokio_shared_rt::test] +#[riven_test] async fn status() -> Result<(), String> { let p = riot_api().lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?; diff --git a/riven/tests/testutils.rs b/riven/tests/testutils.rs index 926074c..d575234 100644 --- a/riven/tests/testutils.rs +++ b/riven/tests/testutils.rs @@ -1,10 +1,41 @@ -#![allow(dead_code)] +#![allow(dead_code, unused_imports)] +#[cfg(not(target_family = "wasm"))] +use std::env::var as env_var; use std::future::Future; use std::sync::OnceLock; +use futures::try_join; use riven::consts::{PlatformRoute, QueueType, RegionalRoute}; use riven::{RiotApi, RiotApiConfig}; +#[cfg(not(target_family = "wasm"))] +pub use tokio_shared_rt::test as riven_test; +#[cfg(target_family = "wasm")] +pub use wasm_bindgen_test::wasm_bindgen_test as riven_test; +#[cfg(target_family = "wasm")] +#[allow(non_upper_case_globals)] +pub fn env_var>(key: K) -> Result { + use wasm_bindgen::prelude::wasm_bindgen; + + #[wasm_bindgen] + extern "C" { + type Process; + static process: Process; + + type Env; + + #[wasm_bindgen(method, getter)] + fn env(this: &Process) -> Env; + + #[wasm_bindgen(method, structural, indexing_getter)] + fn get(this: &Env, field: &str) -> Option; + } + + process + .env() + .get(key.as_ref()) + .ok_or(std::env::VarError::NotPresent) +} #[macro_export] macro_rules! rassert { @@ -40,9 +71,12 @@ static RIOT_API: OnceLock = OnceLock::new(); pub fn riot_api() -> &'static RiotApi { RIOT_API.get_or_init(|| { // Initialize logger here, as a convenient trigger spot. + #[cfg(not(target_family = "wasm"))] env_logger::init(); + #[cfg(target_family = "wasm")] + console_log::init_with_level(log::Level::Info).unwrap(); - let api_key = std::env::var("RGAPI_KEY") + let api_key = env_var("RGAPI_KEY") .ok() .or_else(|| { use std::iter::FromIterator; @@ -112,7 +146,7 @@ pub async fn league_v4_match_v5_latest_combo(route: PlatformRoute) -> Result<(), let mut match_ids: Vec = match_ids.into_iter().flatten().collect(); match_ids.sort_unstable_by(|a, b| a.cmp(b).reverse()); // Sort descending, so latest are first. - let _ = tokio::try_join!( + let _ = try_join!( match_v5_get(route.to_regional(), match_ids.iter().take(NUM_MATCHES)), match_v5_get_timeline(route.to_regional(), match_ids.iter().take(NUM_MATCHES)), )?;