use cookie_store::CookieStore;
use insta::{assert_debug_snapshot, assert_json_snapshot};
use reqwest::{Method, StatusCode};
use snowchains_core::web::{
Atcoder, AtcoderRetrieveSampleTestCasesCredentials, CookieStorage, ProblemsInContest,
RetrieveTestCases, StatusCodeColor,
};
use std::{
fmt,
io::{self, Read as _},
time::Duration,
};
use url::Url;
#[test]
fn abc003_samples() -> anyhow::Result<()> {
test("abc003", || unreachable!())
}
#[test]
fn abc007_samples() -> anyhow::Result<()> {
test("abc007", || unreachable!())
}
#[test]
fn abc019_samples() -> anyhow::Result<()> {
test("abc019", || unreachable!())
}
#[test]
fn agc028_samples() -> anyhow::Result<()> {
test("agc028", || unreachable!())
}
#[test]
fn agc044_samples() -> anyhow::Result<()> {
test("agc044", || unreachable!())
}
#[test]
fn agc047_samples() -> anyhow::Result<()> {
test("agc047", || unreachable!())
}
#[test]
fn arc019_samples() -> anyhow::Result<()> {
test("arc019", || unreachable!())
}
#[test]
fn arc021_samples() -> anyhow::Result<()> {
test("arc021", || unreachable!())
}
#[cfg(feature = "__test_with_credentials")]
#[test]
fn practice_samples() -> anyhow::Result<()> {
use anyhow::Context as _;
use std::env;
fn username_and_password() -> anyhow::Result<(String, String)> {
(|| {
let username = env::var("ATCODER_USERNAME")?;
let password = env::var("ATCODER_PASSWORD")?;
Ok::<_, env::VarError>((username, password))
})()
.with_context(|| "`$ATCODER_USERNAME` and `$ATCODER_PASSWORD` are requied")
}
test("practice", username_and_password)
}
fn test(
contest: &str,
username_and_password: fn() -> anyhow::Result<(String, String)>,
) -> anyhow::Result<()> {
const TIMEOUT: Option<Duration> = Some(Duration::from_secs(30));
struct Shell<'a>(&'a mut Vec<Message>);
impl snowchains_core::web::Shell for Shell<'_> {
fn print_ansi(&mut self, message: &[u8]) -> io::Result<()> {
fn from_utf8(bytes: impl AsRef<[u8]>) -> io::Result<String> {
let mut ret = "".to_owned();
bytes.as_ref().read_to_string(&mut ret)?;
Ok(ret)
}
self.0.push(Message::PrintAnsi(from_utf8(message)?));
Ok(())
}
fn warn<T: fmt::Display>(&mut self, message: T) -> io::Result<()> {
self.0.push(Message::Warn(message.to_string()));
Ok(())
}
fn on_request(&mut self, req: &reqwest::blocking::Request) -> io::Result<()> {
self.0
.push(Message::OnRequest(req.method().clone(), req.url().clone()));
Ok(())
}
fn on_response(
&mut self,
res: &reqwest::blocking::Response,
status_code_color: StatusCodeColor,
) -> std::io::Result<()> {
self.0
.push(Message::OnResponse(res.status(), status_code_color));
Ok(())
}
}
#[derive(Debug)]
enum Message {
PrintAnsi(String),
Warn(String),
OnRequest(Method, Url),
OnResponse(StatusCode, StatusCodeColor),
}
let mut messages = vec![];
let outcome = Atcoder::exec(RetrieveTestCases {
targets: ProblemsInContest::Indexes {
contest: contest.to_owned(),
problems: None,
},
credentials: AtcoderRetrieveSampleTestCasesCredentials {
username_and_password: &mut { username_and_password },
},
full: None,
cookie_storage: CookieStorage {
cookie_store: CookieStore::default(),
on_update: Box::new(|_| Ok(())),
},
timeout: TIMEOUT,
shell: Shell(&mut messages),
})?;
assert_json_snapshot!(format!("{}_samples_outcome", contest), outcome);
assert_debug_snapshot!(format!("{}_samples_messages", contest), messages);
Ok(())
}