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 }
[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"

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;
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
#[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 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(())
},
}
}

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;
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 {
/// 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")
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)
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;
Ok(())
},
}
// Tournament stub test.
tournamentstub: async {
/// 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 {
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())?;
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())?;
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,7 +74,10 @@ async_tests! {
team_size: 5,
allowed_participants: None,
enough_players: false,
}, tournament_id as i64, Some(300))
},
tournament_id as i64,
Some(300),
)
.await;
match codes_result {
@ -80,13 +93,14 @@ async_tests! {
Err(e.to_string())
}
}
},
}
match_v5_get: async {
#[tokio_shared_rt::test]
async fn match_v5_get_test() -> Result<(), String> {
match_v5_get(ROUTE, MATCHES).await
},
match_v5_get_timeline: async {
}
#[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;
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())?;
/// 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.
// raw_response_invalid: async {
// /// 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.
get_nonoptional_invalid: async {
let path_string = format!("/lol/summoner/v4/summoners/by-name/{}", "SUMMONER THAT DOES NOT EXIST");
// }
/// 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::<riven::models::summoner_v4::Summoner>(
"summoner-v4.getBySummonerName", ROUTE.into(), request);
"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");
}
/// 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());
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 {
// /// 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
tft_league_gettopratedladder: async {
let lp = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
// }
/// 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
league_v4_match_v5_latest_combo: async {
/// 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
},
match_v5_get: async {
}
#[tokio_shared_rt::test]
async fn match_v5_get_test() -> Result<(), String> {
match_v5_get(ROUTE.to_regional(), MATCHES).await
},
match_v5_get_timeline: async {
}
#[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;
use colored::*;
use riven::consts::*;
use testutils::*;
@ -27,13 +22,12 @@ static MATCHES: &[&str] = &[
"EUW1_6568537080",
];
async_tests! {
my_runner {
match_v5_get: async {
#[tokio_shared_rt::test]
async fn match_v5_get_test() -> Result<(), String> {
match_v5_get(ROUTE, MATCHES).await
},
match_v5_get_timeline: async {
}
#[tokio_shared_rt::test]
async fn match_v5_get_timeline_test() -> Result<(), String> {
match_v5_get_timeline(ROUTE, MATCHES).await
},
}
}

View File

@ -1,54 +1,58 @@
#![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
#[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);
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
}
#[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))?;
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 {
/// 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())?;
@ -63,16 +67,27 @@ async_tests! {
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 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_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);
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;
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 {
#[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.
// tftstatusv1_getplatformdata: async {
// /// 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(())
// },
tftleaguev1_gettopratedladder: async {
let p = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
// }
#[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());
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())?;
}
#[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(())
},
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())?;
}
#[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(())
},
tftsummonerv1_getbyname_none: async {
let p = RIOT_API.tft_summoner_v1().get_by_summoner_name(ROUTE, "this summoner does not exist");
}
#[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.
tft_combo: async {
let top_players = RIOT_API.tft_league_v1().get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
}
/// 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 = 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);
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);
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,27 +1,28 @@
#![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()
/// /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))?;
.await
.map_err(|e| e.to_string())?
.ok_or_else(|| {
format!(
"Challenge leaderboard with id {} returned 404",
challenge_id
)
})?;
{
rassert!(!leaderboard.is_empty());
@ -36,20 +37,26 @@ async_tests! {
}
// 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))?;
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())?;
/// /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() {
@ -59,30 +66,48 @@ async_tests! {
// 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))?
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 {
/// /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())?;
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))?
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;
use colored::*;
use riven::consts::*;
use riven::models::summoner_v4::*;
use testutils::*;
@ -22,18 +17,30 @@ 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())?;
#[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(())
},
champion_getrotation: async {
}
#[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();
@ -43,113 +50,54 @@ async_tests! {
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);
}
#[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(())
},
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);
}
#[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(())
},
// 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 {
// /// 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
clash_get_tournaments: async {
#[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() {
@ -158,19 +106,22 @@ async_tests! {
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");
}
#[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(())
},
}
status: async {
#[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(())
},
}
}

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;
use colored::*;
use riven::consts::*;
use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::PH2;
async_tests! {
my_runner {
status: async {
#[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(())
},
}
}

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;
use colored::*;
use riven::consts::*;
use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::SG2;
async_tests! {
my_runner {
status: async {
#[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(())
},
}
}

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;
use colored::*;
use riven::consts::*;
use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::TH2;
async_tests! {
my_runner {
status: async {
#[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(())
},
}
}

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;
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);
#[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());
let sl = ll.entries.iter().take(50)
.map(|entry| RIOT_API.summoner_v4().get_by_summoner_id(ROUTE, &entry.summoner_id))
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::<Vec<_>>();
for (i, s) in sl.into_iter().enumerate() {
let summoner: Summoner = s.await
let summoner: Summoner = s
.await
.expect("tokio::spawn join error")
.map_err(|e| e.to_string())?;
println!("{}: {}", i + 1, summoner.name);
}
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;
use colored::*;
use riven::consts::*;
use testutils::RIOT_API;
const ROUTE: ValPlatformRoute = ValPlatformRoute::LATAM;
async_tests! {
my_runner {
val_content_ranked_test: async {
#[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))?;
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()))
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);
for (i, p) in leaderboard.players.iter().take(10).enumerate() {
rassert_eq!(i + 1, p.leaderboard_rank as usize);
println!("{:>2}: {:>4} {:<22} ({} wins)",
println!(
"{:>2}: {:>4} {:<22} ({} wins)",
p.leaderboard_rank,
p.ranked_rating,
format!("{}#{}",
format!(
"{}#{}",
p.game_name.as_deref().unwrap_or("<NONE>"),
p.tag_line.as_deref().unwrap_or("<NONE>")),
p.number_of_wins);
p.tag_line.as_deref().unwrap_or("<NONE>")
),
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;
use colored::*;
use riven::consts::*;
use testutils::*;
const ROUTE: PlatformRoute = PlatformRoute::VN2;
async_tests! {
my_runner {
status: async {
#[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(())
},
}
}

View File

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