test: use `#[tokio_shared_rt::test]` instead of custom macro

`env_logger::init()` moved into `RIOT_API` static initializer
pull/63/head
Mingwei Samuel 2024-02-24 09:28:33 -08:00
parent 672870dcf1
commit 101633bb47
18 changed files with 700 additions and 744 deletions

View File

@ -54,11 +54,11 @@ tokio = { version = "1", default-features = false, features = [ "macros", "parki
tracing = { version = "0.1", optional = true } tracing = { version = "0.1", optional = true }
[dev-dependencies] [dev-dependencies]
colored = "2"
env_logger = "0.10.0" env_logger = "0.10.0"
fake_instant = "0.5.0" fake_instant = "0.5.0"
futures = "0.3" futures = "0.3"
hyper = { version = "0.14", features = [ "server" ] } hyper = { version = "0.14", features = [ "server" ] }
tokio = { version = "1", features = [ "full" ] } tokio = { version = "1", features = [ "full" ] }
tokio-shared-rt = "0.1"
tracing = "0.1" tracing = "0.1"
tracing-subscriber = "0.2" tracing-subscriber = "0.2"

View File

@ -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 )* )
};
}

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::RU; const ROUTE: PlatformRoute = PlatformRoute::RU;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn summoner_leagues() -> Result<(), String> {
summoner_leagues: async { let sum = RIOT_API
let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "d3atomiz3d"); .summoner_v4()
let sum = sum.await .get_by_summoner_name(ROUTE, "d3atomiz3d");
.map_err(|e| format!("Error getting summoner: {}", e))? let sum = sum
.ok_or_else(|| "Failed to find summoner".to_owned())?; .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 p = RIOT_API
let s = p.await.map_err(|e| format!("Error getting league entries: {}", e))?; .league_v4()
let _ = s; .get_league_entries_for_summoner(ROUTE, &sum.id);
Ok(()) let s = p
}, .await
} .map_err(|e| format!("Error getting league entries: {}", e))?;
let _ = s;
Ok(())
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use riven::models::tournament_stub_v5::*; use riven::models::tournament_stub_v5::*;
use testutils::*; use testutils::*;
@ -15,48 +10,63 @@ static MATCHES: &[&str] = &[
"NA1_4924008147", "NA1_4924008147",
]; ];
async_tests! { /// Account-v1
my_runner { #[tokio_shared_rt::test]
// Account-v1 async fn account_v1_getbyriotid_getbypuuid() -> Result<(), String> {
account_v1_getbyriotid_getbypuuid: async { // Game name is case and whitespace insensitive.
// Game name is case and whitespace insensitive. // But tag cannot have spaces. (Is it case sensitive?).
// But tag cannot have spaces. (Is it case sensitive?). let account_tag = RIOT_API
let account_tag = RIOT_API.account_v1().get_by_riot_id(ROUTE, "Lug nuts K", "000") .account_v1()
.await .get_by_riot_id(ROUTE, "Lug nuts K", "000")
.map_err(|e| format!("Failed to get account by riot ID: {}", e))? .await
.ok_or("Riot account not found!".to_owned())?; .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) let account_puuid = RIOT_API
.await .account_v1()
.map_err(|e| format!("Failed to get account by PUUID: {}", e))?; .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. /// Tournament stub test.
tournamentstub: async { #[tokio_shared_rt::test]
let ts = RIOT_API.tournament_stub_v5(); async fn tournamentstub() -> Result<(), String> {
let provider_id = ts.register_provider_data(ROUTE, &ProviderRegistrationParametersV5 { let ts = RIOT_API.tournament_stub_v5();
let provider_id = ts
.register_provider_data(
ROUTE,
&ProviderRegistrationParametersV5 {
region: PlatformRoute::NA1.as_region_str().to_owned(), region: PlatformRoute::NA1.as_region_str().to_owned(),
url: "https://github.com/MingweiSamuel/Riven".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()), name: Some("Riven Tourney :)".to_owned()),
provider_id, 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(), map_type: "SUMMONERS_RIFT".to_owned(),
metadata: Some("eW91IGZvdW5kIHRoZSBzZWNyZXQgbWVzc2FnZQ==".to_owned()), metadata: Some("eW91IGZvdW5kIHRoZSBzZWNyZXQgbWVzc2FnZQ==".to_owned()),
pick_type: "TOURNAMENT_DRAFT".to_owned(), pick_type: "TOURNAMENT_DRAFT".to_owned(),
@ -64,29 +74,33 @@ async_tests! {
team_size: 5, team_size: 5,
allowed_participants: None, allowed_participants: None,
enough_players: false, enough_players: false,
}, tournament_id as i64, Some(300)) },
.await; tournament_id as i64,
Some(300),
)
.await;
match codes_result { match codes_result {
Ok(codes) => { Ok(codes) => {
rassert_eq!(300, codes.len()); rassert_eq!(300, codes.len());
println!("codes: {}", codes.join(", ")); println!("codes: {}", codes.join(", "));
Ok(()) Ok(())
} }
Err(mut e) => { Err(mut e) => {
if let Some(response) = e.take_response() { if let Some(response) = e.take_response() {
eprintln!("{:?}", response.text().await); eprintln!("{:?}", response.text().await);
}
Err(e.to_string())
}
} }
}, Err(e.to_string())
}
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
}

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
@ -27,73 +22,102 @@ static MATCHES: &[&str] = &[
"JP1_419115017", "JP1_419115017",
]; ];
async_tests! { /// Summoner tests.
my_runner { #[tokio_shared_rt::test]
// Summoner tests. async fn summoner_get_kanjikana() -> Result<(), String> {
summoner_get_kanjikana: async { let p = RIOT_API
let p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "私の 頭が かたい"); .summoner_v4()
let s = p.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to get myheadhard".to_owned())?; .get_by_summoner_name(ROUTE, "私の 頭が かたい");
rassert_eq!("私の頭がかたい", s.name); let s = p
Ok(()) .await
}, .map_err(|e| e.to_string())?
.ok_or_else(|| "Failed to get myheadhard".to_owned())?;
// Failure cases. rassert_eq!("私の頭がかたい", s.name);
// // Make sure get_raw_response(...) with invalid path fails as expected. Ok(())
// 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; // Failure cases.
// rassert!(r.is_err());
// Ok(()) // /// Make sure get_raw_response(...) with invalid path fails as expected.
// }, // #[tokio_shared_rt::test]
// summoner_v4().get_by_summoner_name(...) normally returns an option. // async fn raw_response_invalid -> Result<(), String> {
// If we use `get` (instead of `get_optional`) make sure it errors. // let p = RIOT_API.get_raw_response("summoner-v4.getBySummonerName", Region::JP.into(), "INVALID/PATH".to_owned(), None);
get_nonoptional_invalid: async { // let r = p.await;
let path_string = format!("/lol/summoner/v4/summoners/by-name/{}", "SUMMONER THAT DOES NOT EXIST"); // rassert!(r.is_err());
let request = RIOT_API.request(reqwest::Method::GET, ROUTE.into(), &path_string); // Ok(())
let p = RIOT_API.execute_val::<riven::models::summoner_v4::Summoner>( // }
"summoner-v4.getBySummonerName", ROUTE.into(), request);
let r = p.await; /// summoner_v4().get_by_summoner_name(...) normally returns an option.
rassert!(r.is_err()); /// If we use `get` (instead of `get_optional`) make sure it errors.
Ok(()) #[tokio_shared_rt::test]
}, async fn get_nonoptional_invalid() -> Result<(), String> {
// Make sure 403 is handled as expected. let path_string = format!(
tournament_forbidden: async { "/lol/summoner/v4/summoners/by-name/{}",
let p = RIOT_API.tournament_v5().get_tournament_code(ROUTE.to_regional(), "INVALID_CODE"); "SUMMONER THAT DOES NOT EXIST"
let r = p.await; );
rassert!(r.is_err()); let request = RIOT_API.request(reqwest::Method::GET, ROUTE.into(), &path_string);
rassert_eq!(Some(reqwest::StatusCode::FORBIDDEN), r.unwrap_err().status_code()); let p = RIOT_API.execute_val::<riven::models::summoner_v4::Summoner>(
Ok(()) "summoner-v4.getBySummonerName",
}, ROUTE.into(),
request,
// Disabled: Caihonbbt no longer ranked. );
// // tft-league-v1.getLeagueEntriesForSummoner let r = p.await;
// // https://github.com/MingweiSamuel/Riven/issues/25 rassert!(r.is_err());
// tft_league_getleagueentriesforsummoner: async { Ok(())
// 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); /// Check invalid code, make sure 403 is handled as expected.
// let lr = lp.await.map_err(|e| e.to_string())?; #[tokio_shared_rt::test]
// rassert!(!lr.is_empty()); async fn tournament_forbidden() -> Result<(), String> {
// Ok(()) let p = RIOT_API
// }, .tournament_v5()
// tft-league-v1.getTopRatedLadder .get_tournament_code(ROUTE.to_regional(), "INVALID_CODE");
// https://github.com/MingweiSamuel/Riven/issues/24 let r = p.await;
tft_league_gettopratedladder: async { rassert!(r.is_err());
let lp = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); rassert_eq!(
let lr = lp.await.map_err(|e| e.to_string())?; Some(reqwest::StatusCode::FORBIDDEN),
rassert!(!lr.is_empty()); r.unwrap_err().status_code()
Ok(()) );
}, Ok(())
}
// ASIA regional tests
league_v4_match_v5_latest_combo: async { // Disabled: Caihonbbt no longer ranked.
league_v4_match_v5_latest_combo(ROUTE).await // /// tft-league-v1.getLeagueEntriesForSummoner
}, // /// https://github.com/MingweiSamuel/Riven/issues/25
match_v5_get: async { // #[tokio_shared_rt::test]
match_v5_get(ROUTE.to_regional(), MATCHES).await // async fn tft_league_getleagueentriesforsummoner() -> Result<(), String> {
}, // let sp = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "Caihonbbt");
match_v5_get_timeline: async { // let sr = sp.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to get \"Caihonbbt\"".to_owned())?;
match_v5_get_timeline(ROUTE.to_regional(), MATCHES).await // 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
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
@ -27,13 +22,12 @@ static MATCHES: &[&str] = &[
"EUW1_6568537080", "EUW1_6568537080",
]; ];
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn match_v5_get_test() -> Result<(), String> {
match_v5_get: async { match_v5_get(ROUTE, MATCHES).await
match_v5_get(ROUTE, MATCHES).await }
},
match_v5_get_timeline: async { #[tokio_shared_rt::test]
match_v5_get_timeline(ROUTE, MATCHES).await async fn match_v5_get_timeline_test() -> Result<(), String> {
}, match_v5_get_timeline(ROUTE, MATCHES).await
}
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::EUW1; const ROUTE: PlatformRoute = PlatformRoute::EUW1;
async_tests! { // Champion Mastery 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())?;
// let p = RIOT_API.champion_mastery_v4().get_champion_mastery_score(ROUTE, &sum.id); #[tokio_shared_rt::test]
// let s = p.await.map_err(|e| format!("Error getting champion mastery score: {}", e))?; async fn championmastery_getscore_ma5tery() -> Result<(), String> {
// rassert!((969..=1000).contains(&s), "Unexpected ma5tery score: {}.", s); let sum = RIOT_API
// Ok(()) .summoner_v4()
// }, .get_by_summoner_name(ROUTE, "ma5tery");
championmastery_getscore_ma5tery: async { let sum = sum
let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "ma5tery"); .await
let sum = sum.await .map_err(|e| format!("Error getting summoner: {}", e))?
.map_err(|e| format!("Error getting summoner: {}", e))? .ok_or_else(|| "Failed to find summoner".to_owned())?;
.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 p = RIOT_API
let s = p.await.map_err(|e| format!("Error getting champion mastery score: {}", e))?; .champion_mastery_v4()
rassert!((969..=1000).contains(&s), "Unexpected ma5tery score: {}.", s); .get_champion_mastery_score_by_puuid(ROUTE, &sum.puuid);
Ok(()) let s = p
}, .await
championmastery_getall_ma5tery: async { .map_err(|e| format!("Error getting champion mastery score: {}", e))?;
let sum = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "ma5tery"); rassert!(
let sum = sum.await (969..=1000).contains(&s),
.map_err(|e| format!("Error getting summoner: {}", e))? "Unexpected ma5tery score: {}.",
.ok_or_else(|| "Failed to find summoner".to_owned())?; s
);
let p = RIOT_API.champion_mastery_v4().get_all_champion_masteries_by_puuid(ROUTE, &sum.puuid); Ok(())
let s = p.await.map_err(|e| format!("Error getting all champion masteries: {}", e))?; }
rassert!(s.len() >= 142, "Expected masteries: {}.", s.len());
Ok(()) #[tokio_shared_rt::test]
}, async fn championmastery_getall_ma5tery() -> Result<(), String> {
let sum = RIOT_API
// https://github.com/RiotGames/developer-relations/issues/602 .summoner_v4()
spectator_combo: async { .get_by_summoner_name(ROUTE, "ma5tery");
let featured_p = RIOT_API.spectator_v4().get_featured_games(ROUTE); let sum = sum
let featured = featured_p.await.map_err(|e| e.to_string())?; .await
.map_err(|e| format!("Error getting summoner: {}", e))?
if featured.game_list.is_empty() { .ok_or_else(|| "Failed to find summoner".to_owned())?;
eprintln!("Featured game list is empty!");
return Ok(()); let p = RIOT_API
} .champion_mastery_v4()
.get_all_champion_masteries_by_puuid(ROUTE, &sum.puuid);
// let summoner_name = &featured.game_list[0].participants[0].summoner_name; let s = p
// let summoner_p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, summoner_name); .await
// let summoner = summoner_p.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to find summoner".to_owned())?; .map_err(|e| format!("Error getting all champion masteries: {}", e))?;
rassert!(s.len() >= 142, "Expected masteries: {}.", s.len());
let featured_game = &featured.game_list[0]; Ok(())
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))?; /// https://github.com/RiotGames/developer-relations/issues/602
#[tokio_shared_rt::test]
let livegame_p = RIOT_API.spectator_v4().get_current_game_info_by_summoner(ROUTE, &summoner_id); async fn spectator_combo() -> Result<(), String> {
let livegame_o = livegame_p.await.map_err(|e| e.to_string())?; let featured_p = RIOT_API.spectator_v4().get_featured_games(ROUTE);
if let Some(livegame) = livegame_o { let featured = featured_p.await.map_err(|e| e.to_string())?;
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); if featured.game_list.is_empty() {
} eprintln!("Featured game list is empty!");
Ok(()) 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(())
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
@ -19,53 +14,92 @@ static TFT_MATCHES: &[&str] = &[
"EUW1_6807630149", "EUW1_6807630149",
]; ];
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn tftmatchv1_get_list() -> Result<(), String> {
tftmatchv1_get_list: async { tft_match_v1_get(ROUTE.to_regional(), TFT_MATCHES).await
tft_match_v1_get(ROUTE.to_regional(), TFT_MATCHES).await }
},
// /// Don't have acecess to tft-status-v1.
// // Don't have acecess to tft-status-v1. // #[tokio_shared_rt::test]
// tftstatusv1_getplatformdata: async { // async fn tftstatusv1_getplatformdata() -> Result<(), String> {
// let p = RIOT_API.tft_status_v1().get_platform_data(ROUTE); // let p = RIOT_API.tft_status_v1().get_platform_data(ROUTE);
// let _s = p.await.map_err(|e| e.to_string())?; // let _s = p.await.map_err(|e| e.to_string())?;
// Ok(()) // Ok(())
// }, // }
tftleaguev1_gettopratedladder: async {
let p = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); #[tokio_shared_rt::test]
let l = p.await.map_err(|e| e.to_string())?; async fn tftleaguev1_gettopratedladder() -> Result<(), String> {
rassert!(l.len() > 10, "Expected a few ranked players, got: {}.", l.len()); let p = RIOT_API
Ok(()) .tft_league_v1()
}, .get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
tftmatchv1_getmatch: async { let l = p.await.map_err(|e| e.to_string())?;
let p = RIOT_API.tft_match_v1().get_match(ROUTE.to_regional(), "EUW1_6455483163"); rassert!(
let _m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get TFT match.".to_owned())?; l.len() > 10,
Ok(()) "Expected a few ranked players, got: {}.",
}, l.len()
tftsummonerv1_getbyname: async { );
let p = RIOT_API.tft_summoner_v1().get_by_summoner_name(ROUTE, "相当猥琐"); Ok(())
let _s = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get TFT summoner.".to_owned())?; }
Ok(())
}, #[tokio_shared_rt::test]
tftsummonerv1_getbyname_none: async { async fn tftmatchv1_getmatch() -> Result<(), String> {
let p = RIOT_API.tft_summoner_v1().get_by_summoner_name(ROUTE, "this summoner does not exist"); let p = RIOT_API
rassert!(p.await.map_err(|e| e.to_string())?.is_none()); .tft_match_v1()
Ok(()) .get_match(ROUTE.to_regional(), "EUW1_6455483163");
}, let _m = p
// Get top rated player, get some of their matches. .await
tft_combo: async { .map_err(|e| e.to_string())?
let top_players = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO); .ok_or("Failed to get TFT match.".to_owned())?;
let top_players = top_players.await.map_err(|e| e.to_string())?; Ok(())
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); #[tokio_shared_rt::test]
let top_player = top_player.await.map_err(|e| e.to_string())?; async fn tftsummonerv1_getbyname() -> Result<(), String> {
println!("Top player is {} with `puuid` {}.", top_player.name, top_player.puuid); let p = RIOT_API
let match_ids = RIOT_API.tft_match_v1().get_match_ids_by_puuid( .tft_summoner_v1()
ROUTE.to_regional(), &top_player.puuid, Some(10), None, None, None); .get_by_summoner_name(ROUTE, "相当猥琐");
let match_ids = match_ids.await.map_err(|e| e.to_string())?; let _s = p
tft_match_v1_get(ROUTE.to_regional(), &*match_ids).await?; .await
Ok(()) .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(())
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::RIOT_API; use testutils::RIOT_API;
const ROUTE: PlatformRoute = PlatformRoute::LA1; const ROUTE: PlatformRoute = PlatformRoute::LA1;
/// en_US description: "As a laner, get kills before 10 minutes outside your lane (anyone but your lane opponent)" /// 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! { /// /lol/challenges/v1/challenges/{challengeId}/leaderboards/by-level/{level}
my_runner { /// /lol/challenges/v1/player-data/{puuid}
// /lol/challenges/v1/challenges/{challengeId}/leaderboards/by-level/{level} #[tokio_shared_rt::test]
// /lol/challenges/v1/player-data/{puuid} async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> {
lol_challenges_v1_leaderboards_playerdata: async { let challenge_id = CHALLENGE_ID_ARAM_1K_DPM;
let challenge_id = CHALLENGE_ID__ARAM_1K_DPM; let leaderboard = RIOT_API
let leaderboard = RIOT_API.lol_challenges_v1() .lol_challenges_v1()
.get_challenge_leaderboards(ROUTE, challenge_id, Tier::GRANDMASTER, None) .get_challenge_leaderboards(ROUTE, challenge_id, Tier::GRANDMASTER, None)
.await.map_err(|e| e.to_string())? .await
.ok_or_else(|| format!("Challenge leaderboard with id {} returned 404", challenge_id))?; .map_err(|e| e.to_string())?
.ok_or_else(|| {
format!(
"Challenge leaderboard with id {} returned 404",
challenge_id
)
})?;
{ {
rassert!(!leaderboard.is_empty()); rassert!(!leaderboard.is_empty());
let start = leaderboard[0].position; let start = leaderboard[0].position;
// Commented out: leaderboard is not monotonic for some reason. // Commented out: leaderboard is not monotonic for some reason.
// let mut val = leaderboard[0].value; // let mut val = leaderboard[0].value;
for (n, entry) in leaderboard.iter().enumerate() { for (n, entry) in leaderboard.iter().enumerate() {
rassert_eq!(start + (n as i32), entry.position); rassert_eq!(start + (n as i32), entry.position);
// rassert!(entry.val <= val); // rassert!(entry.val <= val);
// val = etnry.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(())
},
} }
// 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(())
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use riven::models::summoner_v4::*; use riven::models::summoner_v4::*;
use testutils::*; use testutils::*;
@ -22,155 +17,111 @@ fn validate_summoners(s1: Summoner, s2: Summoner) -> Result<(), String> {
const ROUTE: PlatformRoute = PlatformRoute::NA1; const ROUTE: PlatformRoute = PlatformRoute::NA1;
async_tests! { // Summoner 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(())
},
// TODO: MATCH-V4 REMOVED. #[tokio_shared_rt::test]
// matchlist_get: async { async fn summoner_double() -> Result<(), String> {
// let sp = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "haha yes"); let l1p = RIOT_API
// let s = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"haha yes\"".to_owned())?; .summoner_v4()
// let mp = RIOT_API.match_v4().get_matchlist(ROUTE, &s.account_id, None, Some(2500), None, None, Some(2600), None, None); .get_by_summoner_name(ROUTE, "lug nuts k");
// let m = mp.await.map_err(|e| e.to_string())?.ok_or("Failed to get matchlist".to_owned())?; let l2p = RIOT_API
// rassert!(m.matches.len() > 0, "Matchlist should not be empty"); .summoner_v4()
// Ok(()) .get_by_summoner_name(ROUTE, "lugnuts k");
// }, let l1 = l1p
// matchlist_get2: async { .await
// let sp = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "haha yes"); .map_err(|e| e.to_string())?
// let s = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"haha yes\"".to_owned())?; .ok_or_else(|| "'lug nuts k' not found!".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 l2 = l2p
// let m = mp.await.map_err(|e| e.to_string())?.ok_or("Failed to get matchlist".to_owned())?; .await
// rassert!(m.matches.len() > 0, "Matchlist should not be empty"); .map_err(|e| e.to_string())?
// Ok(()) .ok_or_else(|| "'lugnuts k' not found!".to_owned())?;
// }, validate_summoners(l1, l2)?;
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())?; #[tokio_shared_rt::test]
// rassert!(!m.participants.is_empty(), "Match should have participants."); async fn champion_getrotation() -> Result<(), String> {
// Ok(()) let p = RIOT_API.champion_v3().get_champion_info(ROUTE);
// }, let d = p.await.map_err(|e| e.to_string())?;
// match_get_bots: async { let new_len = d.free_champion_ids_for_new_players.len();
// let p = RIOT_API.match_v4().get_match(ROUTE, 3251803350); let free_len = d.free_champion_ids.len();
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?; let level = d.max_new_player_level;
// rassert!(!m.participants.is_empty(), "Match should have participants."); rassert!(new_len >= 10, "New len: {}", new_len);
// Ok(()) rassert!(free_len >= 15, "Free len: {}", free_len);
// }, rassert_eq!(10, level, "New player level: {}", level);
// match_get_odyssey: async { Ok(())
// 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."); #[tokio_shared_rt::test]
// Ok(()) async fn leagueexp_get() -> Result<(), String> {
// }, let p = RIOT_API.league_exp_v4().get_league_entries(
// match_get_aram: async { ROUTE,
// let p = RIOT_API.match_v4().get_match(ROUTE, 2961635718); QueueType::RANKED_SOLO_5x5,
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; Tier::CHALLENGER,
// rassert!(!m.participants.is_empty(), "Match should have participants."); Division::I,
// Ok(()) None,
// }, );
// match_get_aram2: async { let d = p.await.map_err(|e| e.to_string())?;
// let p = RIOT_API.match_v4().get_match(ROUTE, 3596184782); if d.is_empty() {
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?; eprintln!("Off-season, challenger league is empty.");
// rassert!(!m.participants.is_empty(), "Match should have participants."); }
// Ok(()) Ok(())
// }, }
// match_get_urf900: async {
// let p = RIOT_API.match_v4().get_match(ROUTE, 2963663381); #[tokio_shared_rt::test]
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; async fn champion_mastery_v4() -> Result<(), String> {
// rassert!(!m.participants.is_empty(), "Match should have participants."); let summoner = RIOT_API
// Ok(()) .summoner_v4()
// }, .get_by_summoner_name(ROUTE, "LugnutsK");
// match_get_tutorial1: async { let summoner = summoner
// let p = RIOT_API.match_v4().get_match(ROUTE, 3432145099); .await
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; .map_err(|e| e.to_string())?
// rassert!(!m.participants.is_empty(), "Match should have participants."); .ok_or_else(|| "'LugnutsK' not found!".to_owned())?;
// Ok(()) let masteries = RIOT_API
// }, .champion_mastery_v4()
// match_get_tutorial2: async { .get_all_champion_masteries_by_puuid(ROUTE, &summoner.puuid);
// let p = RIOT_API.match_v4().get_match(ROUTE, 3432116214); let masteries = masteries.await.map_err(|e| e.to_string())?;
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; rassert!(74 <= masteries.len());
// rassert!(!m.participants.is_empty(), "Match should have participants."); Ok(())
// Ok(()) }
// },
// match_get_tutorial3: async { // Commented out, requires special API key.
// let p = RIOT_API.match_v4().get_match(ROUTE, 3432156790); // /// LOR
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?; // #[tokio_shared_rt::test]
// rassert!(!m.participants.is_empty(), "Match should have participants."); // async fn async fn lor_ranked_get_leaderboards() -> Result<(), String> {
// Ok(()) // let future = RIOT_API.lor_ranked_v1().get_leaderboards(Region::AMERICAS);
// }, // let _leaderboard = future.await.map_err(|e| e.to_string())?;
// 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())?; // CLASH
// rassert!(!m.frames.is_empty(), "Match timeline should have frames.");
// Ok(()) #[tokio_shared_rt::test]
// }, async fn clash_get_tournaments() -> Result<(), String> {
let p = RIOT_API.clash_v1().get_tournaments(ROUTE);
// Commented out, requires special API key. let tours = p.await.map_err(|e| e.to_string())?;
// // LOR if let Some(tour0) = tours.first() {
// lor_ranked_get_leaderboards: async { let p = RIOT_API.clash_v1().get_tournament_by_id(ROUTE, tour0.id);
// let future = RIOT_API.lor_ranked_v1().get_leaderboards(Region::AMERICAS); let tour1 = p.await.map_err(|e| e.to_string())?;
// let _leaderboard = future.await.map_err(|e| e.to_string())?; assert_eq!(Some(tour0.id), tour1.map(|t| t.id));
// Ok(()) }
// }, Ok(())
// CLASH }
clash_get_tournaments: async {
let p = RIOT_API.clash_v1().get_tournaments(ROUTE); #[tokio_shared_rt::test]
let tours = p.await.map_err(|e| e.to_string())?; async fn clash_get_team_by_id_invalid() -> Result<(), String> {
if let Some(tour0) = tours.first() { let p = RIOT_API
let p = RIOT_API.clash_v1().get_tournament_by_id(ROUTE, tour0.id); .clash_v1()
let tour1 = p.await.map_err(|e| e.to_string())?; .get_team_by_id(ROUTE, "00000000-0000-0000-0000-000000000000");
assert_eq!(Some(tour0.id), tour1.map(|t| t.id)); let team = p.await.map_err(|e| e.to_string())?;
} assert!(team.is_none());
Ok(()) Ok(())
}, }
clash_get_team_by_id: async {
let p = RIOT_API.clash_v1().get_team_by_id(ROUTE, "00000000-0000-0000-0000-000000000000"); #[tokio_shared_rt::test]
let team = p.await.map_err(|e| e.to_string())?; async fn status() -> Result<(), String> {
assert!(team.is_none()); let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
Ok(()) let status = p.await.map_err(|e| e.to_string())?;
}, println!("{:?}", status);
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(())
},
}
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::PH2; const ROUTE: PlatformRoute = PlatformRoute::PH2;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn status() -> Result<(), String> {
status: async { let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?;
let status = p.await.map_err(|e| e.to_string())?; println!("{:?}", status);
println!("{:?}", status); Ok(())
Ok(())
},
}
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::SG2; const ROUTE: PlatformRoute = PlatformRoute::SG2;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn status() -> Result<(), String> {
status: async { let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?;
let status = p.await.map_err(|e| e.to_string())?; println!("{:?}", status);
println!("{:?}", status); Ok(())
Ok(())
},
}
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::TH2; const ROUTE: PlatformRoute = PlatformRoute::TH2;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn status() -> Result<(), String> {
status: async { let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?;
let status = p.await.map_err(|e| e.to_string())?; println!("{:?}", status);
println!("{:?}", status); Ok(())
Ok(())
},
}
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use riven::models::summoner_v4::Summoner; use riven::models::summoner_v4::Summoner;
use testutils::RIOT_API; use testutils::RIOT_API;
const ROUTE: PlatformRoute = PlatformRoute::TR1; const ROUTE: PlatformRoute = PlatformRoute::TR1;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn league_summoner_bulk_test() -> Result<(), String> {
league_summoner_bulk_test: async { let p = RIOT_API
let p = RIOT_API.league_v4().get_challenger_league(ROUTE, QueueType::RANKED_SOLO_5x5); .league_v4()
// let p = future_start(p); .get_challenger_league(ROUTE, QueueType::RANKED_SOLO_5x5);
let ll = p.await.map_err(|e| e.to_string())?; // 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) let sl = ll
.map(|entry| RIOT_API.summoner_v4().get_by_summoner_id(ROUTE, &entry.summoner_id)) .entries
.map(tokio::spawn) .iter()
.collect::<Vec<_>>(); .take(50)
.map(|entry| {
RIOT_API
.summoner_v4()
.get_by_summoner_id(ROUTE, &entry.summoner_id)
})
.map(tokio::spawn)
.collect::<Vec<_>>();
for (i, s) in sl.into_iter().enumerate() { for (i, s) in sl.into_iter().enumerate() {
let summoner: Summoner = s.await let summoner: Summoner = s
.expect("tokio::spawn join error") .await
.map_err(|e| e.to_string())?; .expect("tokio::spawn join error")
println!("{}: {}", i + 1, summoner.name); .map_err(|e| e.to_string())?;
} println!("{}: {}", i + 1, summoner.name);
Ok(())
},
} }
Ok(())
} }

View File

@ -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(())
},
}
}

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::RIOT_API; use testutils::RIOT_API;
const ROUTE: ValPlatformRoute = ValPlatformRoute::LATAM; const ROUTE: ValPlatformRoute = ValPlatformRoute::LATAM;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn val_content_ranked_test() -> Result<(), String> {
val_content_ranked_test: async { let p = RIOT_API.val_content_v1().get_content(ROUTE, Some("zh-CN"));
let p = RIOT_API.val_content_v1().get_content(ROUTE, Some("zh-CN")); let contents = p
let contents = p.await.map_err(|e| format!("Failed to get content: {}", e))?; .await
.map_err(|e| format!("Failed to get content: {}", e))?;
// Find the LAST active act, via `.rev().find(...)`. // 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 // 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 // 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())) let act = contents
.ok_or(format!("No active acts of {} found.", contents.acts.len()))?; .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 p = RIOT_API
let leaderboard = p.await.map_err(|e| e.to_string())? .val_ranked_v1()
.ok_or(format!("Failed to get act leaderboard {} {}.", act.id, act.name))?; .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() { for (i, p) in leaderboard.players.iter().take(10).enumerate() {
rassert_eq!(i + 1, p.leaderboard_rank as usize); rassert_eq!(i + 1, p.leaderboard_rank as usize);
println!("{:>2}: {:>4} {:<22} ({} wins)", println!(
p.leaderboard_rank, "{:>2}: {:>4} {:<22} ({} wins)",
p.ranked_rating, p.leaderboard_rank,
format!("{}#{}", p.ranked_rating,
p.game_name.as_deref().unwrap_or("<NONE>"), format!(
p.tag_line.as_deref().unwrap_or("<NONE>")), "{}#{}",
p.number_of_wins); p.game_name.as_deref().unwrap_or("<NONE>"),
} p.tag_line.as_deref().unwrap_or("<NONE>")
),
Ok(()) p.number_of_wins
}, );
} }
Ok(())
} }

View File

@ -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; mod testutils;
use colored::*;
use riven::consts::*; use riven::consts::*;
use testutils::*; use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::VN2; const ROUTE: PlatformRoute = PlatformRoute::VN2;
async_tests! { #[tokio_shared_rt::test]
my_runner { async fn status() -> Result<(), String> {
status: async { let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE); let status = p.await.map_err(|e| e.to_string())?;
let status = p.await.map_err(|e| e.to_string())?; println!("{:?}", status);
println!("{:?}", status); Ok(())
Ok(())
},
}
} }

View File

@ -6,8 +6,41 @@ use lazy_static::lazy_static;
use riven::consts::{PlatformRoute, QueueType, RegionalRoute}; use riven::consts::{PlatformRoute, QueueType, RegionalRoute};
use riven::{RiotApi, RiotApiConfig}; 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! { lazy_static! {
pub static ref RIOT_API: RiotApi = { 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") let api_key = std::env::var("RGAPI_KEY")
.ok() .ok()
.or_else(|| std::fs::read_to_string("apikey.txt").ok()) .or_else(|| std::fs::read_to_string("apikey.txt").ok())