From 101633bb47f995e756851b0dd7dc6e62a97dcc58 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Sat, 24 Feb 2024 09:28:33 -0800 Subject: [PATCH] test: use `#[tokio_shared_rt::test]` instead of custom macro `env_logger::init()` moved into `RIOT_API` static initializer --- riven/Cargo.toml | 2 +- riven/tests/async_tests.rs | 87 ----------- riven/tests/test_ru.rs | 35 ++--- riven/tests/tests_americas.rs | 128 ++++++++------- riven/tests/tests_asia_jp.rs | 172 +++++++++++--------- riven/tests/tests_europe.rs | 22 +-- riven/tests/tests_euw.rs | 153 ++++++++++-------- riven/tests/tests_euw_tft.rs | 142 ++++++++++------- riven/tests/tests_la1.rs | 179 ++++++++++++--------- riven/tests/tests_na.rs | 261 +++++++++++++------------------ riven/tests/tests_ph2.rs | 20 +-- riven/tests/tests_sg2.rs | 20 +-- riven/tests/tests_th2.rs | 20 +-- riven/tests/tests_tr.rs | 52 +++--- riven/tests/tests_tw2.rs.ignored | 25 --- riven/tests/tests_val_latam.rs | 73 +++++---- riven/tests/tests_vn2.rs | 20 +-- riven/tests/testutils.rs | 33 ++++ 18 files changed, 700 insertions(+), 744 deletions(-) delete mode 100644 riven/tests/async_tests.rs delete mode 100644 riven/tests/tests_tw2.rs.ignored diff --git a/riven/Cargo.toml b/riven/Cargo.toml index f831bd0..d3073dc 100644 --- a/riven/Cargo.toml +++ b/riven/Cargo.toml @@ -54,11 +54,11 @@ tokio = { version = "1", default-features = false, features = [ "macros", "parki tracing = { version = "0.1", optional = true } [dev-dependencies] -colored = "2" env_logger = "0.10.0" fake_instant = "0.5.0" futures = "0.3" hyper = { version = "0.14", features = [ "server" ] } tokio = { version = "1", features = [ "full" ] } +tokio-shared-rt = "0.1" tracing = "0.1" tracing-subscriber = "0.2" diff --git a/riven/tests/async_tests.rs b/riven/tests/async_tests.rs deleted file mode 100644 index fdfc4de..0000000 --- a/riven/tests/async_tests.rs +++ /dev/null @@ -1,87 +0,0 @@ -/// This is just a huge hack to make a test runner (with no test cases) -/// look as if it's running a bunch of (async) test cases. -#[macro_export] -macro_rules! async_tests { - ( $runner:ident { $( $name:ident : async $eval:block, )* } ) => { - #[allow(dead_code)] - fn $runner(_: &[()]) { - env_logger::init(); - - std::process::exit({ - let rt = tokio::runtime::Runtime::new() - .expect("Failed to create runtime."); - - let (_, errs) = rt.block_on(async { - println!(); - println!("running tests"); - println!(); - let mut oks: u32 = 0; - let mut errs: u32 = 0; - $( - let $name = async { - let result: std::result::Result<(), String> = async { - $eval - }.await; - result - }; - let $name = tokio::spawn($name); - )* - $( - let $name = $name.await.expect("Failed to spawn."); - )* - $( - print!("test {} ... ", stringify!($name)); - match $name { - Ok(_) => { - println!("{}", "ok".green()); - oks += 1; - } - Err(msg) => { - println!("{}", "error".bright_red()); - println!("{}", msg); - errs += 1; - } - } - )* - println!(); - print!("test result: {}. ", if errs > 0 { "error".bright_red() } else { "ok".green() }); - println!("{} passed; {} failed; 0 ignored; 0 measured; 0 filtered out", oks, errs); - println!(); - (oks, errs) - }); - // Just returns #errs as exit code. - errs as i32 - }); - } - }; -} - -#[macro_export] -macro_rules! rassert { - ( $x:expr ) => { - { - if $x { Ok(()) } else { Err(stringify!($x)) }? - } - }; - ( $x:expr, $format:expr $(, $arg:expr)* ) => { - { - if $x { Ok(()) } else { Err( format!($format $(, $arg )* ) ) }? - } - }; -} - -#[macro_export] -macro_rules! rassert_eq { - ( $a:expr, $b:expr ) => { rassert!($a == $b) }; - ( $a:expr, $b:expr, $format:expr $(, $arg:expr)* ) => { - rassert!($a == $b, $format $(, $arg )* ) - }; -} - -#[macro_export] -macro_rules! rassert_ne { - ( $a:expr, $b:expr ) => { rassert!($a != $b) }; - ( $a:expr, $b:expr, $format:expr $(, $arg:expr)* ) => { - rassert!($a != $b, $format $(, $arg )* ) - }; -} diff --git a/riven/tests/test_ru.rs b/riven/tests/test_ru.rs index 1e945e2..708f086 100644 --- a/riven/tests/test_ru.rs +++ b/riven/tests/test_ru.rs @@ -1,26 +1,25 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::RU; -async_tests! { - my_runner { - summoner_leagues: async { - let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "d3atomiz3d"); - let sum = sum.await - .map_err(|e| format!("Error getting summoner: {}", e))? - .ok_or_else(|| "Failed to find summoner".to_owned())?; +#[tokio_shared_rt::test] +async fn summoner_leagues() -> Result<(), String> { + let sum = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "d3atomiz3d"); + let sum = sum + .await + .map_err(|e| format!("Error getting summoner: {}", e))? + .ok_or_else(|| "Failed to find summoner".to_owned())?; - let p = RIOT_API.league_v4().get_league_entries_for_summoner(ROUTE, &sum.id); - let s = p.await.map_err(|e| format!("Error getting league entries: {}", e))?; - let _ = s; - Ok(()) - }, - } + let p = RIOT_API + .league_v4() + .get_league_entries_for_summoner(ROUTE, &sum.id); + let s = p + .await + .map_err(|e| format!("Error getting league entries: {}", e))?; + let _ = s; + Ok(()) } diff --git a/riven/tests/tests_americas.rs b/riven/tests/tests_americas.rs index 6696246..e0edf03 100644 --- a/riven/tests/tests_americas.rs +++ b/riven/tests/tests_americas.rs @@ -1,9 +1,4 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use riven::models::tournament_stub_v5::*; use testutils::*; @@ -15,48 +10,63 @@ static MATCHES: &[&str] = &[ "NA1_4924008147", ]; -async_tests! { - my_runner { - // Account-v1 - account_v1_getbyriotid_getbypuuid: async { - // Game name is case and whitespace insensitive. - // But tag cannot have spaces. (Is it case sensitive?). - let account_tag = RIOT_API.account_v1().get_by_riot_id(ROUTE, "Lug nuts K", "000") - .await - .map_err(|e| format!("Failed to get account by riot ID: {}", e))? - .ok_or("Riot account not found!".to_owned())?; +/// Account-v1 +#[tokio_shared_rt::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?). + let account_tag = RIOT_API + .account_v1() + .get_by_riot_id(ROUTE, "Lug nuts K", "000") + .await + .map_err(|e| format!("Failed to get account by riot ID: {}", e))? + .ok_or("Riot account not found!".to_owned())?; - let account_puuid = RIOT_API.account_v1().get_by_puuid(ROUTE, &account_tag.puuid) - .await - .map_err(|e| format!("Failed to get account by PUUID: {}", e))?; + let account_puuid = RIOT_API + .account_v1() + .get_by_puuid(ROUTE, &account_tag.puuid) + .await + .map_err(|e| format!("Failed to get account by PUUID: {}", e))?; - let _ = account_puuid; + let _ = account_puuid; - Ok(()) - }, + Ok(()) +} - // Tournament stub test. - tournamentstub: async { - let ts = RIOT_API.tournament_stub_v5(); - let provider_id = ts.register_provider_data(ROUTE, &ProviderRegistrationParametersV5 { +/// Tournament stub test. +#[tokio_shared_rt::test] +async fn tournamentstub() -> Result<(), String> { + let ts = RIOT_API.tournament_stub_v5(); + let provider_id = ts + .register_provider_data( + ROUTE, + &ProviderRegistrationParametersV5 { region: PlatformRoute::NA1.as_region_str().to_owned(), url: "https://github.com/MingweiSamuel/Riven".to_owned(), - }) - .await - .map_err(|e| e.to_string())?; + }, + ) + .await + .map_err(|e| e.to_string())?; - println!("provider_id: {}", provider_id); + println!("provider_id: {}", provider_id); - let tournament_id = ts.register_tournament(ROUTE, &TournamentRegistrationParametersV5 { + let tournament_id = ts + .register_tournament( + ROUTE, + &TournamentRegistrationParametersV5 { name: Some("Riven Tourney :)".to_owned()), provider_id, - }) - .await - .map_err(|e| e.to_string())?; + }, + ) + .await + .map_err(|e| e.to_string())?; - println!("tournament_id: {}", tournament_id); + println!("tournament_id: {}", tournament_id); - let codes_result = ts.create_tournament_code(ROUTE, &TournamentCodeParametersV5 { + let codes_result = ts + .create_tournament_code( + ROUTE, + &TournamentCodeParametersV5 { map_type: "SUMMONERS_RIFT".to_owned(), metadata: Some("eW91IGZvdW5kIHRoZSBzZWNyZXQgbWVzc2FnZQ==".to_owned()), pick_type: "TOURNAMENT_DRAFT".to_owned(), @@ -64,29 +74,33 @@ async_tests! { team_size: 5, allowed_participants: None, enough_players: false, - }, tournament_id as i64, Some(300)) - .await; + }, + tournament_id as i64, + Some(300), + ) + .await; - match codes_result { - Ok(codes) => { - rassert_eq!(300, codes.len()); - println!("codes: {}", codes.join(", ")); - Ok(()) - } - Err(mut e) => { - if let Some(response) = e.take_response() { - eprintln!("{:?}", response.text().await); - } - Err(e.to_string()) - } + match codes_result { + Ok(codes) => { + rassert_eq!(300, codes.len()); + println!("codes: {}", codes.join(", ")); + Ok(()) + } + Err(mut e) => { + if let Some(response) = e.take_response() { + eprintln!("{:?}", response.text().await); } - }, - - match_v5_get: async { - match_v5_get(ROUTE, MATCHES).await - }, - match_v5_get_timeline: async { - match_v5_get_timeline(ROUTE, MATCHES).await - }, + Err(e.to_string()) + } } } + +#[tokio_shared_rt::test] +async fn match_v5_get_test() -> Result<(), String> { + match_v5_get(ROUTE, MATCHES).await +} + +#[tokio_shared_rt::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 5149cc9..4bb4688 100644 --- a/riven/tests/tests_asia_jp.rs +++ b/riven/tests/tests_asia_jp.rs @@ -1,9 +1,4 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; @@ -27,73 +22,102 @@ static MATCHES: &[&str] = &[ "JP1_419115017", ]; -async_tests! { - my_runner { - // Summoner tests. - summoner_get_kanjikana: async { - let p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "私の 頭が かたい"); - let s = p.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to get myheadhard".to_owned())?; - rassert_eq!("私の頭がかたい", s.name); - Ok(()) - }, - - // Failure cases. - // // Make sure get_raw_response(...) with invalid path fails as expected. - // raw_response_invalid: async { - // let p = RIOT_API.get_raw_response("summoner-v4.getBySummonerName", Region::JP.into(), "INVALID/PATH".to_owned(), None); - // let r = p.await; - // rassert!(r.is_err()); - // Ok(()) - // }, - // summoner_v4().get_by_summoner_name(...) normally returns an option. - // If we use `get` (instead of `get_optional`) make sure it errors. - get_nonoptional_invalid: async { - let path_string = format!("/lol/summoner/v4/summoners/by-name/{}", "SUMMONER THAT DOES NOT EXIST"); - let request = RIOT_API.request(reqwest::Method::GET, ROUTE.into(), &path_string); - let p = RIOT_API.execute_val::( - "summoner-v4.getBySummonerName", ROUTE.into(), request); - let r = p.await; - rassert!(r.is_err()); - Ok(()) - }, - // Make sure 403 is handled as expected. - tournament_forbidden: async { - let p = RIOT_API.tournament_v5().get_tournament_code(ROUTE.to_regional(), "INVALID_CODE"); - let r = p.await; - rassert!(r.is_err()); - rassert_eq!(Some(reqwest::StatusCode::FORBIDDEN), r.unwrap_err().status_code()); - Ok(()) - }, - - // Disabled: Caihonbbt no longer ranked. - // // tft-league-v1.getLeagueEntriesForSummoner - // // https://github.com/MingweiSamuel/Riven/issues/25 - // tft_league_getleagueentriesforsummoner: async { - // 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())?; - // let lp = RIOT_API.tft_league_v1().get_league_entries_for_summoner(ROUTE, &sr.id); - // let lr = lp.await.map_err(|e| e.to_string())?; - // rassert!(!lr.is_empty()); - // Ok(()) - // }, - // tft-league-v1.getTopRatedLadder - // https://github.com/MingweiSamuel/Riven/issues/24 - tft_league_gettopratedladder: async { - let lp = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); - let lr = lp.await.map_err(|e| e.to_string())?; - rassert!(!lr.is_empty()); - Ok(()) - }, - - // ASIA regional tests - league_v4_match_v5_latest_combo: async { - league_v4_match_v5_latest_combo(ROUTE).await - }, - match_v5_get: async { - match_v5_get(ROUTE.to_regional(), MATCHES).await - }, - match_v5_get_timeline: async { - match_v5_get_timeline(ROUTE.to_regional(), MATCHES).await - }, - } +/// Summoner tests. +#[tokio_shared_rt::test] +async fn summoner_get_kanjikana() -> Result<(), String> { + let p = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "私の 頭が かたい"); + let s = p + .await + .map_err(|e| e.to_string())? + .ok_or_else(|| "Failed to get myheadhard".to_owned())?; + rassert_eq!("私の頭がかたい", s.name); + Ok(()) +} + +// Failure cases. + +// /// Make sure get_raw_response(...) with invalid path fails as expected. +// #[tokio_shared_rt::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; +// rassert!(r.is_err()); +// Ok(()) +// } + +/// 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] +async fn get_nonoptional_invalid() -> Result<(), String> { + let path_string = format!( + "/lol/summoner/v4/summoners/by-name/{}", + "SUMMONER THAT DOES NOT EXIST" + ); + let request = RIOT_API.request(reqwest::Method::GET, ROUTE.into(), &path_string); + let p = RIOT_API.execute_val::( + "summoner-v4.getBySummonerName", + ROUTE.into(), + request, + ); + let r = p.await; + rassert!(r.is_err()); + Ok(()) +} + +/// Check invalid code, make sure 403 is handled as expected. +#[tokio_shared_rt::test] +async fn tournament_forbidden() -> Result<(), String> { + let p = RIOT_API + .tournament_v5() + .get_tournament_code(ROUTE.to_regional(), "INVALID_CODE"); + let r = p.await; + rassert!(r.is_err()); + rassert_eq!( + Some(reqwest::StatusCode::FORBIDDEN), + r.unwrap_err().status_code() + ); + Ok(()) +} + +// Disabled: Caihonbbt no longer ranked. +// /// tft-league-v1.getLeagueEntriesForSummoner +// /// https://github.com/MingweiSamuel/Riven/issues/25 +// #[tokio_shared_rt::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())?; +// let lp = RIOT_API.tft_league_v1().get_league_entries_for_summoner(ROUTE, &sr.id); +// let lr = lp.await.map_err(|e| e.to_string())?; +// rassert!(!lr.is_empty()); +// Ok(()) +// } + +/// tft-league-v1.getTopRatedLadder +/// https://github.com/MingweiSamuel/Riven/issues/24 +#[tokio_shared_rt::test] +async fn tft_league_gettopratedladder() -> Result<(), String> { + let lp = RIOT_API + .tft_league_v1() + .get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); + let lr = lp.await.map_err(|e| e.to_string())?; + rassert!(!lr.is_empty()); + Ok(()) +} + +/// ASIA regional tests +#[tokio_shared_rt::test] +async fn league_v4_match_v5_latest_combo_test() -> Result<(), String> { + league_v4_match_v5_latest_combo(ROUTE).await +} + +#[tokio_shared_rt::test] +async fn match_v5_get_test() -> Result<(), String> { + match_v5_get(ROUTE.to_regional(), MATCHES).await +} + +#[tokio_shared_rt::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 b9b5f2f..b969af6 100644 --- a/riven/tests/tests_europe.rs +++ b/riven/tests/tests_europe.rs @@ -1,9 +1,4 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; @@ -27,13 +22,12 @@ static MATCHES: &[&str] = &[ "EUW1_6568537080", ]; -async_tests! { - my_runner { - match_v5_get: async { - match_v5_get(ROUTE, MATCHES).await - }, - match_v5_get_timeline: async { - match_v5_get_timeline(ROUTE, MATCHES).await - }, - } +#[tokio_shared_rt::test] +async fn match_v5_get_test() -> Result<(), String> { + match_v5_get(ROUTE, MATCHES).await +} + +#[tokio_shared_rt::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 b93ac08..053d52f 100644 --- a/riven/tests/tests_euw.rs +++ b/riven/tests/tests_euw.rs @@ -1,78 +1,93 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::EUW1; -async_tests! { - my_runner { - // Champion Mastery tests. - // SUMMONER ID ENDPOINT BROKEN: https://github.com/RiotGames/developer-relations/issues/830 - // championmastery_getscore_ma5tery: async { - // let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "ma5tery"); - // let sum = sum.await - // .map_err(|e| format!("Error getting summoner: {}", e))? - // .ok_or_else(|| "Failed to find summoner".to_owned())?; +// Champion Mastery tests - // let p = RIOT_API.champion_mastery_v4().get_champion_mastery_score(ROUTE, &sum.id); - // let s = p.await.map_err(|e| format!("Error getting champion mastery score: {}", e))?; - // rassert!((969..=1000).contains(&s), "Unexpected ma5tery score: {}.", s); - // Ok(()) - // }, - championmastery_getscore_ma5tery: async { - let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "ma5tery"); - let sum = sum.await - .map_err(|e| format!("Error getting summoner: {}", e))? - .ok_or_else(|| "Failed to find summoner".to_owned())?; +#[tokio_shared_rt::test] +async fn championmastery_getscore_ma5tery() -> Result<(), String> { + let sum = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "ma5tery"); + let sum = sum + .await + .map_err(|e| format!("Error getting summoner: {}", e))? + .ok_or_else(|| "Failed to find summoner".to_owned())?; - let p = RIOT_API.champion_mastery_v4().get_champion_mastery_score_by_puuid(ROUTE, &sum.puuid); - let s = p.await.map_err(|e| format!("Error getting champion mastery score: {}", e))?; - rassert!((969..=1000).contains(&s), "Unexpected ma5tery score: {}.", s); - Ok(()) - }, - championmastery_getall_ma5tery: async { - let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "ma5tery"); - let sum = sum.await - .map_err(|e| format!("Error getting summoner: {}", e))? - .ok_or_else(|| "Failed to find summoner".to_owned())?; - - let p = RIOT_API.champion_mastery_v4().get_all_champion_masteries_by_puuid(ROUTE, &sum.puuid); - let s = p.await.map_err(|e| format!("Error getting all champion masteries: {}", e))?; - rassert!(s.len() >= 142, "Expected masteries: {}.", s.len()); - Ok(()) - }, - - // https://github.com/RiotGames/developer-relations/issues/602 - spectator_combo: async { - let featured_p = RIOT_API.spectator_v4().get_featured_games(ROUTE); - let featured = featured_p.await.map_err(|e| e.to_string())?; - - if featured.game_list.is_empty() { - eprintln!("Featured game list is empty!"); - return Ok(()); - } - - // let summoner_name = &featured.game_list[0].participants[0].summoner_name; - // let summoner_p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, summoner_name); - // let summoner = summoner_p.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to find summoner".to_owned())?; - - let featured_game = &featured.game_list[0]; - let participant = &featured_game.participants[0]; - let summoner_id = participant.summoner_id.as_ref() - .ok_or_else(|| format!("Summoner in spectator featured game missing summoner ID: {}", &participant.summoner_name))?; - - let livegame_p = RIOT_API.spectator_v4().get_current_game_info_by_summoner(ROUTE, &summoner_id); - let livegame_o = livegame_p.await.map_err(|e| e.to_string())?; - if let Some(livegame) = livegame_o { - let participant_match = livegame.participants.iter().find(|p| p.summoner_name == participant.summoner_name); - rassert!(participant_match.is_some(), "Failed to find summoner in match: {}.", &participant.summoner_name); - } - Ok(()) - }, - } + let p = RIOT_API + .champion_mastery_v4() + .get_champion_mastery_score_by_puuid(ROUTE, &sum.puuid); + let s = p + .await + .map_err(|e| format!("Error getting champion mastery score: {}", e))?; + rassert!( + (969..=1000).contains(&s), + "Unexpected ma5tery score: {}.", + s + ); + Ok(()) +} + +#[tokio_shared_rt::test] +async fn championmastery_getall_ma5tery() -> Result<(), String> { + let sum = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "ma5tery"); + let sum = sum + .await + .map_err(|e| format!("Error getting summoner: {}", e))? + .ok_or_else(|| "Failed to find summoner".to_owned())?; + + let p = RIOT_API + .champion_mastery_v4() + .get_all_champion_masteries_by_puuid(ROUTE, &sum.puuid); + let s = p + .await + .map_err(|e| format!("Error getting all champion masteries: {}", e))?; + rassert!(s.len() >= 142, "Expected masteries: {}.", s.len()); + Ok(()) +} + +/// https://github.com/RiotGames/developer-relations/issues/602 +#[tokio_shared_rt::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())?; + + if featured.game_list.is_empty() { + eprintln!("Featured game list is empty!"); + return Ok(()); + } + + // let summoner_name = &featured.game_list[0].participants[0].summoner_name; + // let summoner_p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, summoner_name); + // let summoner = summoner_p.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to find summoner".to_owned())?; + + let featured_game = &featured.game_list[0]; + let participant = &featured_game.participants[0]; + let summoner_id = participant.summoner_id.as_ref().ok_or_else(|| { + format!( + "Summoner in spectator featured game missing summoner ID: {}", + &participant.summoner_name + ) + })?; + + let livegame_p = RIOT_API + .spectator_v4() + .get_current_game_info_by_summoner(ROUTE, &summoner_id); + let livegame_o = livegame_p.await.map_err(|e| e.to_string())?; + if let Some(livegame) = livegame_o { + let participant_match = livegame + .participants + .iter() + .find(|p| p.summoner_name == participant.summoner_name); + rassert!( + participant_match.is_some(), + "Failed to find summoner in match: {}.", + &participant.summoner_name + ); + } + Ok(()) } diff --git a/riven/tests/tests_euw_tft.rs b/riven/tests/tests_euw_tft.rs index 21e43f9..c09ec52 100644 --- a/riven/tests/tests_euw_tft.rs +++ b/riven/tests/tests_euw_tft.rs @@ -1,9 +1,4 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; @@ -19,53 +14,92 @@ static TFT_MATCHES: &[&str] = &[ "EUW1_6807630149", ]; -async_tests! { - my_runner { - tftmatchv1_get_list: async { - tft_match_v1_get(ROUTE.to_regional(), TFT_MATCHES).await - }, - - // // Don't have acecess to tft-status-v1. - // tftstatusv1_getplatformdata: async { - // let p = RIOT_API.tft_status_v1().get_platform_data(ROUTE); - // let _s = p.await.map_err(|e| e.to_string())?; - // Ok(()) - // }, - tftleaguev1_gettopratedladder: async { - let p = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); - let l = p.await.map_err(|e| e.to_string())?; - rassert!(l.len() > 10, "Expected a few ranked players, got: {}.", l.len()); - Ok(()) - }, - tftmatchv1_getmatch: async { - let p = RIOT_API.tft_match_v1().get_match(ROUTE.to_regional(), "EUW1_6455483163"); - let _m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get TFT match.".to_owned())?; - Ok(()) - }, - tftsummonerv1_getbyname: async { - let p = RIOT_API.tft_summoner_v1().get_by_summoner_name(ROUTE, "相当猥琐"); - let _s = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get TFT summoner.".to_owned())?; - Ok(()) - }, - tftsummonerv1_getbyname_none: async { - let p = RIOT_API.tft_summoner_v1().get_by_summoner_name(ROUTE, "this summoner does not exist"); - rassert!(p.await.map_err(|e| e.to_string())?.is_none()); - Ok(()) - }, - // Get top rated player, get some of their matches. - tft_combo: async { - let top_players = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); - let top_players = top_players.await.map_err(|e| e.to_string())?; - rassert!(!top_players.is_empty()); - let top_player_entry = &top_players[0]; - let top_player = RIOT_API.tft_summoner_v1().get_by_summoner_id(ROUTE, &top_player_entry.summoner_id); - let top_player = top_player.await.map_err(|e| e.to_string())?; - println!("Top player is {} with `puuid` {}.", top_player.name, top_player.puuid); - let match_ids = RIOT_API.tft_match_v1().get_match_ids_by_puuid( - ROUTE.to_regional(), &top_player.puuid, Some(10), None, None, None); - let match_ids = match_ids.await.map_err(|e| e.to_string())?; - tft_match_v1_get(ROUTE.to_regional(), &*match_ids).await?; - Ok(()) - }, - } +#[tokio_shared_rt::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] +// 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] +async fn tftleaguev1_gettopratedladder() -> Result<(), String> { + let p = RIOT_API + .tft_league_v1() + .get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); + let l = p.await.map_err(|e| e.to_string())?; + rassert!( + l.len() > 10, + "Expected a few ranked players, got: {}.", + l.len() + ); + Ok(()) +} + +#[tokio_shared_rt::test] +async fn tftmatchv1_getmatch() -> Result<(), String> { + let p = RIOT_API + .tft_match_v1() + .get_match(ROUTE.to_regional(), "EUW1_6455483163"); + let _m = p + .await + .map_err(|e| e.to_string())? + .ok_or("Failed to get TFT match.".to_owned())?; + Ok(()) +} + +#[tokio_shared_rt::test] +async fn tftsummonerv1_getbyname() -> Result<(), String> { + let p = RIOT_API + .tft_summoner_v1() + .get_by_summoner_name(ROUTE, "相当猥琐"); + let _s = p + .await + .map_err(|e| e.to_string())? + .ok_or("Failed to get TFT summoner.".to_owned())?; + Ok(()) +} + +#[tokio_shared_rt::test] +async fn tftsummonerv1_getbyname_none() -> Result<(), String> { + let p = RIOT_API + .tft_summoner_v1() + .get_by_summoner_name(ROUTE, "this summoner does not exist"); + rassert!(p.await.map_err(|e| e.to_string())?.is_none()); + Ok(()) +} + +/// Get top rated player, get some of their matches. +#[tokio_shared_rt::test] +async fn tft_combo() -> Result<(), String> { + let top_players = RIOT_API + .tft_league_v1() + .get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); + let top_players = top_players.await.map_err(|e| e.to_string())?; + rassert!(!top_players.is_empty()); + let top_player_entry = &top_players[0]; + let top_player = RIOT_API + .tft_summoner_v1() + .get_by_summoner_id(ROUTE, &top_player_entry.summoner_id); + let top_player = top_player.await.map_err(|e| e.to_string())?; + println!( + "Top player is {} with `puuid` {}.", + top_player.name, top_player.puuid + ); + let match_ids = RIOT_API.tft_match_v1().get_match_ids_by_puuid( + ROUTE.to_regional(), + &top_player.puuid, + Some(10), + None, + None, + None, + ); + let match_ids = match_ids.await.map_err(|e| e.to_string())?; + tft_match_v1_get(ROUTE.to_regional(), &*match_ids).await?; + Ok(()) } diff --git a/riven/tests/tests_la1.rs b/riven/tests/tests_la1.rs index 2db98a1..e1c7bfa 100644 --- a/riven/tests/tests_la1.rs +++ b/riven/tests/tests_la1.rs @@ -1,88 +1,113 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::RIOT_API; const ROUTE: PlatformRoute = PlatformRoute::LA1; /// en_US description: "As a laner, get kills before 10 minutes outside your lane (anyone but your lane opponent)" -const CHALLENGE_ID__ARAM_1K_DPM: i64 = 101101; +const CHALLENGE_ID_ARAM_1K_DPM: i64 = 101101; -async_tests! { - my_runner { - // /lol/challenges/v1/challenges/{challengeId}/leaderboards/by-level/{level} - // /lol/challenges/v1/player-data/{puuid} - lol_challenges_v1_leaderboards_playerdata: async { - let challenge_id = CHALLENGE_ID__ARAM_1K_DPM; - let leaderboard = RIOT_API.lol_challenges_v1() - .get_challenge_leaderboards(ROUTE, challenge_id, Tier::GRANDMASTER, None) - .await.map_err(|e| e.to_string())? - .ok_or_else(|| format!("Challenge leaderboard with id {} returned 404", challenge_id))?; +/// /lol/challenges/v1/challenges/{challengeId}/leaderboards/by-level/{level} +/// /lol/challenges/v1/player-data/{puuid} +#[tokio_shared_rt::test] +async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> { + let challenge_id = CHALLENGE_ID_ARAM_1K_DPM; + let leaderboard = RIOT_API + .lol_challenges_v1() + .get_challenge_leaderboards(ROUTE, challenge_id, Tier::GRANDMASTER, None) + .await + .map_err(|e| e.to_string())? + .ok_or_else(|| { + format!( + "Challenge leaderboard with id {} returned 404", + challenge_id + ) + })?; - { - rassert!(!leaderboard.is_empty()); - let start = leaderboard[0].position; - // Commented out: leaderboard is not monotonic for some reason. - // let mut val = leaderboard[0].value; - for (n, entry) in leaderboard.iter().enumerate() { - rassert_eq!(start + (n as i32), entry.position); - // rassert!(entry.val <= val); - // val = etnry.val; - } - } - - // Spot check 10% for `player-data`. - for entry in leaderboard.iter().step_by(10) - { - let _player_data = RIOT_API.lol_challenges_v1().get_player_data(ROUTE, &entry.puuid) - .await.map_err(|e| format!("Failed to get player data PUUID {}: {}", entry.puuid, e))?; - } - - Ok(()) - }, - - // /lol/challenges/v1/challenges/config - // /lol/challenges/v1/challenges/{challengeId}/config - lol_challenges_v1_check_configs: async { - let challenges = RIOT_API.lol_challenges_v1().get_all_challenge_configs(ROUTE) - .await.map_err(|e| e.to_string())?; - rassert!(!challenges.is_empty()); - - for challenge in challenges.iter() { - rassert!(!challenge.localized_names.is_empty()); - rassert!(!challenge.thresholds.is_empty()); - } - - // Spot-check 10% of the challenge IDs. - for challenge in challenges.iter().step_by(10) { - RIOT_API.lol_challenges_v1().get_challenge_configs(ROUTE, challenge.id) - .await.map_err(|e| format!("Failed to get challenge config with id {}\n{}", challenge.id, e))? - .ok_or_else(|| format!("Challenge config with id {} returned 404", challenge.id))?; - } - - Ok(()) - }, - - // /lol/challenges/v1/challenges/percentiles - // /lol/challenges/v1/challenges/{challengeId}/percentiles - lol_challenges_v1_check_percentiles: async { - // Check all percentiles. - let percentiles = RIOT_API.lol_challenges_v1().get_all_challenge_percentiles(ROUTE) - .await.map_err(|e| e.to_string())?; - rassert!(!percentiles.is_empty()); - - // Spot-check 10% of the challenge IDs. - for &challenge_id in percentiles.keys().step_by(10) { - RIOT_API.lol_challenges_v1().get_challenge_percentiles(ROUTE, challenge_id) - .await.map_err(|e| format!("Failed to get challenge percentile with id {}\n{}", challenge_id, e))? - .ok_or_else(|| format!("Challenge percentile with id {} returned 404", challenge_id))?; - } - - Ok(()) - }, + { + rassert!(!leaderboard.is_empty()); + let start = leaderboard[0].position; + // Commented out: leaderboard is not monotonic for some reason. + // let mut val = leaderboard[0].value; + for (n, entry) in leaderboard.iter().enumerate() { + rassert_eq!(start + (n as i32), entry.position); + // rassert!(entry.val <= val); + // val = etnry.val; + } } + + // Spot check 10% for `player-data`. + for entry in leaderboard.iter().step_by(10) { + let _player_data = RIOT_API + .lol_challenges_v1() + .get_player_data(ROUTE, &entry.puuid) + .await + .map_err(|e| format!("Failed to get player data PUUID {}: {}", entry.puuid, e))?; + } + + Ok(()) +} + +/// /lol/challenges/v1/challenges/config +/// /lol/challenges/v1/challenges/{challengeId}/config +#[tokio_shared_rt::test] +async fn lol_challenges_v1_check_configs() -> Result<(), String> { + let challenges = RIOT_API + .lol_challenges_v1() + .get_all_challenge_configs(ROUTE) + .await + .map_err(|e| e.to_string())?; + rassert!(!challenges.is_empty()); + + for challenge in challenges.iter() { + rassert!(!challenge.localized_names.is_empty()); + rassert!(!challenge.thresholds.is_empty()); + } + + // Spot-check 10% of the challenge IDs. + for challenge in challenges.iter().step_by(10) { + RIOT_API + .lol_challenges_v1() + .get_challenge_configs(ROUTE, challenge.id) + .await + .map_err(|e| { + format!( + "Failed to get challenge config with id {}\n{}", + challenge.id, e + ) + })? + .ok_or_else(|| format!("Challenge config with id {} returned 404", challenge.id))?; + } + + Ok(()) +} + +/// /lol/challenges/v1/challenges/percentiles +/// /lol/challenges/v1/challenges/{challengeId}/percentiles +#[tokio_shared_rt::test] +async fn lol_challenges_v1_check_percentiles() -> Result<(), String> { + // Check all percentiles. + let percentiles = RIOT_API + .lol_challenges_v1() + .get_all_challenge_percentiles(ROUTE) + .await + .map_err(|e| e.to_string())?; + rassert!(!percentiles.is_empty()); + + // Spot-check 10% of the challenge IDs. + for &challenge_id in percentiles.keys().step_by(10) { + RIOT_API + .lol_challenges_v1() + .get_challenge_percentiles(ROUTE, challenge_id) + .await + .map_err(|e| { + format!( + "Failed to get challenge percentile with id {}\n{}", + challenge_id, e + ) + })? + .ok_or_else(|| format!("Challenge percentile with id {} returned 404", challenge_id))?; + } + + Ok(()) } diff --git a/riven/tests/tests_na.rs b/riven/tests/tests_na.rs index 3a80cb7..dbed12b 100644 --- a/riven/tests/tests_na.rs +++ b/riven/tests/tests_na.rs @@ -1,9 +1,4 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use riven::models::summoner_v4::*; use testutils::*; @@ -22,155 +17,111 @@ fn validate_summoners(s1: Summoner, s2: Summoner) -> Result<(), String> { const ROUTE: PlatformRoute = PlatformRoute::NA1; -async_tests! { - my_runner { - // Summoner tests. - summoner_double: async { - let l1p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "lug nuts k"); - let l2p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "lugnuts k"); - let l1 = l1p.await.map_err(|e| e.to_string())?.ok_or_else(|| "'lug nuts k' not found!".to_owned())?; - let l2 = l2p.await.map_err(|e| e.to_string())?.ok_or_else(|| "'lugnuts k' not found!".to_owned())?; - validate_summoners(l1, l2)?; - Ok(()) - }, - champion_getrotation: async { - let p = RIOT_API.champion_v3().get_champion_info(ROUTE); - let d = p.await.map_err(|e| e.to_string())?; - let new_len = d.free_champion_ids_for_new_players.len(); - let free_len = d.free_champion_ids.len(); - let level = d.max_new_player_level; - rassert!(new_len >= 10, "New len: {}", new_len); - rassert!(free_len >= 15, "Free len: {}", free_len); - rassert_eq!(10, level, "New player level: {}", level); - Ok(()) - }, - leagueexp_get: async { - let p = RIOT_API.league_exp_v4().get_league_entries(ROUTE, QueueType::RANKED_SOLO_5x5, Tier::CHALLENGER, Division::I, None); - let d = p.await.map_err(|e| e.to_string())?; - if d.is_empty() { - eprintln!("Off-season, challenger league is empty."); - } - Ok(()) - }, - champion_mastery_v4: async { - let summoner = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "LugnutsK"); - let summoner = summoner.await.map_err(|e| e.to_string())?.ok_or_else(|| "'LugnutsK' not found!".to_owned())?; - let masteries = RIOT_API.champion_mastery_v4().get_all_champion_masteries_by_puuid(ROUTE, &summoner.puuid); - let masteries = masteries.await.map_err(|e| e.to_string())?; - rassert!(74 <= masteries.len()); - Ok(()) - }, +// Summoner tests. - // TODO: MATCH-V4 REMOVED. - // matchlist_get: async { - // let sp = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "haha yes"); - // let s = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"haha yes\"".to_owned())?; - // let mp = RIOT_API.match_v4().get_matchlist(ROUTE, &s.account_id, None, Some(2500), None, None, Some(2600), None, None); - // let m = mp.await.map_err(|e| e.to_string())?.ok_or("Failed to get matchlist".to_owned())?; - // rassert!(m.matches.len() > 0, "Matchlist should not be empty"); - // Ok(()) - // }, - // matchlist_get2: async { - // let sp = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "haha yes"); - // let s = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"haha yes\"".to_owned())?; - // let mp = RIOT_API.match_v4().get_matchlist(ROUTE, &s.account_id, None, None, Some(&[ Champion::SION, Champion::SIVIR, Champion::CASSIOPEIA ]), None, None, None, None); - // let m = mp.await.map_err(|e| e.to_string())?.ok_or("Failed to get matchlist".to_owned())?; - // rassert!(m.matches.len() > 0, "Matchlist should not be empty"); - // Ok(()) - // }, - - // match_get: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 3190191338); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_bots: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 3251803350); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_odyssey: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 2881976826); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_aram: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 2961635718); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_aram2: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 3596184782); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_urf900: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 2963663381); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_tutorial1: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 3432145099); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_tutorial2: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 3432116214); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - // match_get_tutorial3: async { - // let p = RIOT_API.match_v4().get_match(ROUTE, 3432156790); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; - // rassert!(!m.participants.is_empty(), "Match should have participants."); - // Ok(()) - // }, - - // match_gettimeline: async { - // let p = RIOT_API.match_v4().get_match_timeline(ROUTE, 3190191338); - // let m = p.await.map_err(|e| e.to_string())?.ok_or("Match timeline not found.".to_owned())?; - // rassert!(!m.frames.is_empty(), "Match timeline should have frames."); - // Ok(()) - // }, - - // Commented out, requires special API key. - // // LOR - // lor_ranked_get_leaderboards: async { - // let future = RIOT_API.lor_ranked_v1().get_leaderboards(Region::AMERICAS); - // let _leaderboard = future.await.map_err(|e| e.to_string())?; - // Ok(()) - // }, - // CLASH - clash_get_tournaments: async { - let p = RIOT_API.clash_v1().get_tournaments(ROUTE); - let tours = p.await.map_err(|e| e.to_string())?; - if let Some(tour0) = tours.first() { - let p = RIOT_API.clash_v1().get_tournament_by_id(ROUTE, tour0.id); - let tour1 = p.await.map_err(|e| e.to_string())?; - assert_eq!(Some(tour0.id), tour1.map(|t| t.id)); - } - Ok(()) - }, - clash_get_team_by_id: async { - let p = RIOT_API.clash_v1().get_team_by_id(ROUTE, "00000000-0000-0000-0000-000000000000"); - let team = p.await.map_err(|e| e.to_string())?; - assert!(team.is_none()); - Ok(()) - }, - - status: async { - let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); - let status = p.await.map_err(|e| e.to_string())?; - println!("{:?}", status); - Ok(()) - }, - } +#[tokio_shared_rt::test] +async fn summoner_double() -> Result<(), String> { + let l1p = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "lug nuts k"); + let l2p = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "lugnuts k"); + let l1 = l1p + .await + .map_err(|e| e.to_string())? + .ok_or_else(|| "'lug nuts k' not found!".to_owned())?; + let l2 = l2p + .await + .map_err(|e| e.to_string())? + .ok_or_else(|| "'lugnuts k' not found!".to_owned())?; + validate_summoners(l1, l2)?; + Ok(()) +} + +#[tokio_shared_rt::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())?; + let new_len = d.free_champion_ids_for_new_players.len(); + let free_len = d.free_champion_ids.len(); + let level = d.max_new_player_level; + rassert!(new_len >= 10, "New len: {}", new_len); + rassert!(free_len >= 15, "Free len: {}", free_len); + rassert_eq!(10, level, "New player level: {}", level); + Ok(()) +} + +#[tokio_shared_rt::test] +async fn leagueexp_get() -> Result<(), String> { + let p = RIOT_API.league_exp_v4().get_league_entries( + ROUTE, + QueueType::RANKED_SOLO_5x5, + Tier::CHALLENGER, + Division::I, + None, + ); + let d = p.await.map_err(|e| e.to_string())?; + if d.is_empty() { + eprintln!("Off-season, challenger league is empty."); + } + Ok(()) +} + +#[tokio_shared_rt::test] +async fn champion_mastery_v4() -> Result<(), String> { + let summoner = RIOT_API + .summoner_v4() + .get_by_summoner_name(ROUTE, "LugnutsK"); + let summoner = summoner + .await + .map_err(|e| e.to_string())? + .ok_or_else(|| "'LugnutsK' not found!".to_owned())?; + let masteries = RIOT_API + .champion_mastery_v4() + .get_all_champion_masteries_by_puuid(ROUTE, &summoner.puuid); + let masteries = masteries.await.map_err(|e| e.to_string())?; + rassert!(74 <= masteries.len()); + Ok(()) +} + +// Commented out, requires special API key. +// /// LOR +// #[tokio_shared_rt::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())?; +// Ok(()) +// } + +// CLASH + +#[tokio_shared_rt::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())?; + if let Some(tour0) = tours.first() { + let p = RIOT_API.clash_v1().get_tournament_by_id(ROUTE, tour0.id); + let tour1 = p.await.map_err(|e| e.to_string())?; + assert_eq!(Some(tour0.id), tour1.map(|t| t.id)); + } + Ok(()) +} + +#[tokio_shared_rt::test] +async fn clash_get_team_by_id_invalid() -> Result<(), String> { + let p = RIOT_API + .clash_v1() + .get_team_by_id(ROUTE, "00000000-0000-0000-0000-000000000000"); + let team = p.await.map_err(|e| e.to_string())?; + assert!(team.is_none()); + Ok(()) +} + +#[tokio_shared_rt::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())?; + println!("{:?}", status); + Ok(()) } diff --git a/riven/tests/tests_ph2.rs b/riven/tests/tests_ph2.rs index e4d3d89..fc938aa 100644 --- a/riven/tests/tests_ph2.rs +++ b/riven/tests/tests_ph2.rs @@ -1,21 +1,13 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::PH2; -async_tests! { - my_runner { - status: async { - let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); - let status = p.await.map_err(|e| e.to_string())?; - println!("{:?}", status); - Ok(()) - }, - } +#[tokio_shared_rt::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())?; + println!("{:?}", status); + Ok(()) } diff --git a/riven/tests/tests_sg2.rs b/riven/tests/tests_sg2.rs index bfcdc19..890fe74 100644 --- a/riven/tests/tests_sg2.rs +++ b/riven/tests/tests_sg2.rs @@ -1,21 +1,13 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::SG2; -async_tests! { - my_runner { - status: async { - let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); - let status = p.await.map_err(|e| e.to_string())?; - println!("{:?}", status); - Ok(()) - }, - } +#[tokio_shared_rt::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())?; + println!("{:?}", status); + Ok(()) } diff --git a/riven/tests/tests_th2.rs b/riven/tests/tests_th2.rs index 34c134a..5219a4e 100644 --- a/riven/tests/tests_th2.rs +++ b/riven/tests/tests_th2.rs @@ -1,21 +1,13 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::TH2; -async_tests! { - my_runner { - status: async { - let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); - let status = p.await.map_err(|e| e.to_string())?; - println!("{:?}", status); - Ok(()) - }, - } +#[tokio_shared_rt::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())?; + println!("{:?}", status); + Ok(()) } diff --git a/riven/tests/tests_tr.rs b/riven/tests/tests_tr.rs index 1fce1e0..2d60c89 100644 --- a/riven/tests/tests_tr.rs +++ b/riven/tests/tests_tr.rs @@ -1,37 +1,39 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use riven::models::summoner_v4::Summoner; use testutils::RIOT_API; const ROUTE: PlatformRoute = PlatformRoute::TR1; -async_tests! { - my_runner { - league_summoner_bulk_test: async { - 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())?; +#[tokio_shared_rt::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())?; - println!("{:?} Challenger {} entries.", ROUTE, ll.entries.len()); + println!("{:?} Challenger {} entries.", ROUTE, ll.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 sl = ll + .entries + .iter() + .take(50) + .map(|entry| { + RIOT_API + .summoner_v4() + .get_by_summoner_id(ROUTE, &entry.summoner_id) + }) + .map(tokio::spawn) + .collect::>(); - for (i, s) in sl.into_iter().enumerate() { - let summoner: Summoner = s.await - .expect("tokio::spawn join error") - .map_err(|e| e.to_string())?; - println!("{}: {}", i + 1, summoner.name); - } - - Ok(()) - }, + for (i, s) in sl.into_iter().enumerate() { + let summoner: Summoner = s + .await + .expect("tokio::spawn join error") + .map_err(|e| e.to_string())?; + println!("{}: {}", i + 1, summoner.name); } + + Ok(()) } diff --git a/riven/tests/tests_tw2.rs.ignored b/riven/tests/tests_tw2.rs.ignored deleted file mode 100644 index f46fca4..0000000 --- a/riven/tests/tests_tw2.rs.ignored +++ /dev/null @@ -1,25 +0,0 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; -mod testutils; -use testutils::*; - -use colored::*; - -use riven::consts::*; - -const ROUTE: PlatformRoute = PlatformRoute::TW2; - -async_tests!{ - my_runner { - // TODO: for some reason status is not available on TW2... - // https://developer.riotgames.com/apis#lol-status-v4/GET_getPlatformData - status: async { - let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); - let status = p.await.map_err(|e| e.to_string())?; - println!("{:?}", status); - Ok(()) - }, - } -} diff --git a/riven/tests/tests_val_latam.rs b/riven/tests/tests_val_latam.rs index fe7ea70..e54f68c 100644 --- a/riven/tests/tests_val_latam.rs +++ b/riven/tests/tests_val_latam.rs @@ -1,44 +1,53 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::RIOT_API; const ROUTE: ValPlatformRoute = ValPlatformRoute::LATAM; -async_tests! { - my_runner { - val_content_ranked_test: async { - let p = RIOT_API.val_content_v1().get_content(ROUTE, Some("zh-CN")); - let contents = p.await.map_err(|e| format!("Failed to get content: {}", e))?; +#[tokio_shared_rt::test] +async fn val_content_ranked_test() -> Result<(), String> { + let p = RIOT_API.val_content_v1().get_content(ROUTE, Some("zh-CN")); + let contents = p + .await + .map_err(|e| format!("Failed to get content: {}", e))?; - // Find the LAST active act, via `.rev().find(...)`. - // Added filter when parent id is 0000... as there are multiple that are active, the last active seems to be episode 5 - // Not sure if this a bandaid fix - let act = contents.acts.iter().rev().find(|act| act.is_active && act.parent_id != Some("00000000-0000-0000-0000-000000000000".to_string())) - .ok_or(format!("No active acts of {} found.", contents.acts.len()))?; + // Find the LAST active act, via `.rev().find(...)`. + // Added filter when parent id is 0000... as there are multiple that are active, the last active seems to be episode 5 + // Not sure if this a bandaid fix + let act = contents + .acts + .iter() + .rev() + .find(|act| { + act.is_active + && act.parent_id != Some("00000000-0000-0000-0000-000000000000".to_string()) + }) + .ok_or(format!("No active acts of {} found.", contents.acts.len()))?; - let p = RIOT_API.val_ranked_v1().get_leaderboard(ROUTE, &act.id, None, None); - let leaderboard = p.await.map_err(|e| e.to_string())? - .ok_or(format!("Failed to get act leaderboard {} {}.", act.id, act.name))?; + let p = RIOT_API + .val_ranked_v1() + .get_leaderboard(ROUTE, &act.id, None, None); + let leaderboard = p.await.map_err(|e| e.to_string())?.ok_or(format!( + "Failed to get act leaderboard {} {}.", + act.id, act.name + ))?; - rassert_eq!(act.id, leaderboard.act_id); + rassert_eq!(act.id, leaderboard.act_id); - for (i, p) in leaderboard.players.iter().take(10).enumerate() { - rassert_eq!(i + 1, p.leaderboard_rank as usize); - println!("{:>2}: {:>4} {:<22} ({} wins)", - p.leaderboard_rank, - p.ranked_rating, - format!("{}#{}", - p.game_name.as_deref().unwrap_or(""), - p.tag_line.as_deref().unwrap_or("")), - p.number_of_wins); - } - - Ok(()) - }, + for (i, p) in leaderboard.players.iter().take(10).enumerate() { + rassert_eq!(i + 1, p.leaderboard_rank as usize); + println!( + "{:>2}: {:>4} {:<22} ({} wins)", + p.leaderboard_rank, + p.ranked_rating, + format!( + "{}#{}", + p.game_name.as_deref().unwrap_or(""), + p.tag_line.as_deref().unwrap_or("") + ), + p.number_of_wins + ); } + + Ok(()) } diff --git a/riven/tests/tests_vn2.rs b/riven/tests/tests_vn2.rs index 305afc2..db2f5fd 100644 --- a/riven/tests/tests_vn2.rs +++ b/riven/tests/tests_vn2.rs @@ -1,21 +1,13 @@ -#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))] -#![cfg_attr(feature = "nightly", test_runner(my_runner))] - -mod async_tests; mod testutils; -use colored::*; use riven::consts::*; use testutils::*; const ROUTE: PlatformRoute = PlatformRoute::VN2; -async_tests! { - my_runner { - status: async { - let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); - let status = p.await.map_err(|e| e.to_string())?; - println!("{:?}", status); - Ok(()) - }, - } +#[tokio_shared_rt::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())?; + println!("{:?}", status); + Ok(()) } diff --git a/riven/tests/testutils.rs b/riven/tests/testutils.rs index 7412903..8973ded 100644 --- a/riven/tests/testutils.rs +++ b/riven/tests/testutils.rs @@ -6,8 +6,41 @@ use lazy_static::lazy_static; use riven::consts::{PlatformRoute, QueueType, RegionalRoute}; use riven::{RiotApi, RiotApiConfig}; +#[macro_export] +macro_rules! rassert { + ( $x:expr ) => { + { + if $x { Ok(()) } else { Err(stringify!($x)) }? + } + }; + ( $x:expr, $format:expr $(, $arg:expr)* ) => { + { + if $x { Ok(()) } else { Err( format!($format $(, $arg )* ) ) }? + } + }; +} + +#[macro_export] +macro_rules! rassert_eq { + ( $a:expr, $b:expr ) => { rassert!($a == $b) }; + ( $a:expr, $b:expr, $format:expr $(, $arg:expr)* ) => { + rassert!($a == $b, $format $(, $arg )* ) + }; +} + +#[macro_export] +macro_rules! rassert_ne { + ( $a:expr, $b:expr ) => { rassert!($a != $b) }; + ( $a:expr, $b:expr, $format:expr $(, $arg:expr)* ) => { + rassert!($a != $b, $format $(, $arg )* ) + }; +} + lazy_static! { pub static ref RIOT_API: RiotApi = { + // Initialize logger here, as a convenient trigger spot. + env_logger::init(); + let api_key = std::env::var("RGAPI_KEY") .ok() .or_else(|| std::fs::read_to_string("apikey.txt").ok())