Skip to content

Commit

Permalink
Add default_match: Match field to RetrieveTestCases
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Mar 1, 2021
1 parent 9beaef1 commit d276049
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 33 deletions.
2 changes: 2 additions & 0 deletions snowchains_core/examples/atcoder-retrieve-test-cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use cookie_store::CookieStore;
use indicatif::ProgressDrawTarget;
use snowchains_core::{
color_spec,
testsuite::Match,
web::{
Atcoder, AtcoderRetrieveFullTestCasesCredentials,
AtcoderRetrieveSampleTestCasesCredentials, CookieStorage, ProblemsInContest,
Expand Down Expand Up @@ -62,6 +63,7 @@ fn main() -> anyhow::Result<()> {
credentials: AtcoderRetrieveSampleTestCasesCredentials {
username_and_password: &mut username_and_password(credentials),
},
default_match: Match::Lines,
full: if full {
Some(RetrieveFullTestCases {
credentials: AtcoderRetrieveFullTestCasesCredentials {
Expand Down
2 changes: 2 additions & 0 deletions snowchains_core/examples/codeforces-retrieve-test-cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use cookie_store::CookieStore;
use indicatif::ProgressDrawTarget;
use snowchains_core::{
color_spec,
testsuite::Match,
web::{
Codeforces, CodeforcesRetrieveSampleTestCasesCredentials, CookieStorage, ProblemsInContest,
RetrieveTestCases, StatusCodeColor,
Expand Down Expand Up @@ -57,6 +58,7 @@ fn main() -> anyhow::Result<()> {
credentials: CodeforcesRetrieveSampleTestCasesCredentials {
username_and_password: &mut username_and_password(credentials),
},
default_match: Match::Lines,
full: None,
cookie_storage: CookieStorage {
cookie_store: CookieStore::default(),
Expand Down
2 changes: 2 additions & 0 deletions snowchains_core/examples/yukicoder-retrieve-test-cases.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use indicatif::ProgressDrawTarget;
use snowchains_core::{
color_spec,
testsuite::Match,
web::{
RetrieveFullTestCases, RetrieveTestCases, StatusCodeColor, Yukicoder,
YukicoderRetrieveFullTestCasesCredentials, YukicoderRetrieveTestCasesTargets,
Expand Down Expand Up @@ -71,6 +72,7 @@ fn main() -> anyhow::Result<()> {
),
},
credentials: (),
default_match: Match::Lines,
full: if full {
Some(RetrieveFullTestCases {
credentials: YukicoderRetrieveFullTestCasesCredentials {
Expand Down
53 changes: 37 additions & 16 deletions snowchains_core/src/web/atcoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ impl<S: Shell> Exec<RetrieveTestCases<Self, S>> for Atcoder<'_> {
AtcoderRetrieveSampleTestCasesCredentials {
username_and_password,
},
default_match,
full,
cookie_storage,
timeout,
Expand All @@ -209,7 +210,8 @@ impl<S: Shell> Exec<RetrieveTestCases<Self, S>> for Atcoder<'_> {

let mut sess = Session::new(timeout, Some(cookie_storage), shell)?;

let mut outcome = retrieve_sample_test_cases(&mut sess, username_and_password, &targets)?;
let mut outcome =
retrieve_sample_test_cases(&mut sess, username_and_password, &targets, &default_match)?;

if let Some(RetrieveFullTestCases {
credentials:
Expand Down Expand Up @@ -700,6 +702,7 @@ fn retrieve_sample_test_cases(
mut sess: impl SessionMut,
mut username_and_password: impl FnMut() -> anyhow::Result<(String, String)>,
targets: &ProblemsInContest,
default_match: &Match,
) -> anyhow::Result<RetrieveTestCasesOutcome> {
let problems = match targets.clone() {
ProblemsInContest::Indexes { contest, problems } => {
Expand Down Expand Up @@ -782,7 +785,7 @@ fn retrieve_sample_test_cases(
.send()?
.ensure_status(&[200])?
.html()?
.extract_samples();
.extract_samples(default_match);

if indexes_and_urls.len() > test_suites.len() {
sess.shell().warn(format!(
Expand Down Expand Up @@ -816,7 +819,7 @@ fn retrieve_sample_test_cases(

TestSuite::Batch(BatchTestSuite {
timelimit: None,
r#match: Match::Lines,
r#match: default_match.clone(),
cases: vec![],
extend: vec![],
})
Expand Down Expand Up @@ -1521,7 +1524,10 @@ impl Html {
.with_context(|| "Could not extract task indexes and URLs")
}

fn extract_samples(&self) -> Vec<anyhow::Result<(String, String, anyhow::Result<TestSuite>)>> {
fn extract_samples(
&self,
default_match: &Match,
) -> Vec<anyhow::Result<(String, String, anyhow::Result<TestSuite>)>> {
return self
.select(static_selector!(
"#main-container > div.row div[class=\"col-sm-12\"]",
Expand Down Expand Up @@ -1556,7 +1562,7 @@ impl Html {
.select(static_selector!(":scope > div[id=\"task-statement\"]"))
.exactly_one()
.ok()
.and_then(extract_samples)
.and_then(|r| extract_samples(r, default_match))
.ok_or("Could not extract the sample cases")?;

Ok::<_, &str>(if timelimit == Duration::new(0, 0) {
Expand Down Expand Up @@ -1611,7 +1617,10 @@ impl Html {
Some(Duration::from_millis(timelimit))
}

fn extract_samples(task_statement: ElementRef<'_>) -> Option<Samples> {
fn extract_samples(
task_statement: ElementRef<'_>,
default_match: &Match,
) -> Option<Samples> {
// TODO:
// - https://atcoder.jp/contests/arc019/tasks/arc019_4 (interactive)
// - https://atcoder.jp/contests/arc021/tasks/arc021_4 (interactive)
Expand Down Expand Up @@ -1658,15 +1667,26 @@ impl Html {
static P8_CONTENT: Lazy<Selector> =
lazy_selector!("span.lang > span.lang-ja > div.part > section > pre");

let stmt = task_statement;
try_extract_samples(stmt, &P1_HEAD, &P1_CONTENT, &IN_JA, &OUT_JA)
.or_else(|| try_extract_samples(stmt, &P2_HEAD, &P2_CONTENT, &IN_EN, &OUT_EN))
.or_else(|| try_extract_samples(stmt, &P3_HEAD, &P3_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(stmt, &P4_HEAD, &P4_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(stmt, &P5_HEAD, &P5_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(stmt, &P6_HEAD, &P6_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(stmt, &P7_HEAD, &P7_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(stmt, &P8_HEAD, &P8_CONTENT, &IN_JA, &OUT_JA))
let try_extract_samples =
|selector_for_header, selector_for_content, re_input, re_output| {
try_extract_samples(
task_statement,
selector_for_header,
selector_for_content,
re_input,
re_output,
default_match,
)
};

try_extract_samples(&P1_HEAD, &P1_CONTENT, &IN_JA, &OUT_JA)
.or_else(|| try_extract_samples(&P2_HEAD, &P2_CONTENT, &IN_EN, &OUT_EN))
.or_else(|| try_extract_samples(&P3_HEAD, &P3_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(&P4_HEAD, &P4_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(&P5_HEAD, &P5_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(&P6_HEAD, &P6_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(&P7_HEAD, &P7_CONTENT, &IN_JA, &OUT_JA))
.or_else(|| try_extract_samples(&P8_HEAD, &P8_CONTENT, &IN_JA, &OUT_JA))
}

fn try_extract_samples(
Expand All @@ -1675,6 +1695,7 @@ impl Html {
selector_for_content: &'static Selector,
re_input: &'static Regex,
re_output: &'static Regex,
default_match: &Match,
) -> Option<Samples> {
#[allow(clippy::blocks_in_if_conditions)]
if task_statement
Expand Down Expand Up @@ -1717,7 +1738,7 @@ impl Html {
relative_error: None,
absolute_error: Some(error),
},
_ => Match::Lines,
_ => default_match.clone(),
}
};

Expand Down
7 changes: 4 additions & 3 deletions snowchains_core/src/web/codeforces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ impl<S: Shell> Exec<RetrieveTestCases<Self, S>> for Codeforces<'_> {
CodeforcesRetrieveSampleTestCasesCredentials {
mut username_and_password,
},
default_match,
full: _,
cookie_storage,
timeout,
Expand Down Expand Up @@ -207,7 +208,7 @@ impl<S: Shell> Exec<RetrieveTestCases<Self, S>> for Codeforces<'_> {
.colorize_status_code(&[200], (), ..)
.send()?
.html()?
.extract_test_cases()?;
.extract_test_cases(&default_match)?;

Ok(Some(RetrieveTestCasesOutcomeProblem {
contest: Some(contest.clone()),
Expand Down Expand Up @@ -541,7 +542,7 @@ impl Html {
.with_context(|| "Could not extract problem names")
}

fn extract_test_cases(&self) -> anyhow::Result<TestSuite> {
fn extract_test_cases(&self, default_match: &Match) -> anyhow::Result<TestSuite> {
let timelimit = self
.select(static_selector!("#pageContent div.time-limit"))
.flat_map(|r| r.text())
Expand Down Expand Up @@ -579,7 +580,7 @@ impl Html {
{
todo!();
}
let r#match = Match::Lines;
let r#match = default_match.clone();

let sample_test = self
.select(static_selector!("#pageContent div.sample-test"))
Expand Down
3 changes: 2 additions & 1 deletion snowchains_core/src/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub use crate::web::{
},
};

use crate::testsuite::TestSuite;
use crate::testsuite::{Match, TestSuite};
use anyhow::{anyhow, bail, Context as _};
use cookie_store::CookieStore;
use derivative::Derivative;
Expand Down Expand Up @@ -291,6 +291,7 @@ impl RetrieveLanguagesOutcome {
pub struct RetrieveTestCases<P: Platform, S: Shell> {
pub targets: P::RetrieveTestCasesTargets,
pub credentials: P::RetrieveTestCasesCredentials,
pub default_match: Match,
pub full: Option<RetrieveFullTestCases<P>>,
pub cookie_storage: P::CookieStorage,
pub timeout: Option<Duration>,
Expand Down
17 changes: 10 additions & 7 deletions snowchains_core/src/web/yukicoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl<S: Shell> Exec<RetrieveTestCases<Self, S>> for Yukicoder {
let RetrieveTestCases {
targets,
credentials: (),
default_match,
full,
cookie_storage: (),
timeout,
Expand All @@ -90,7 +91,7 @@ impl<S: Shell> Exec<RetrieveTestCases<Self, S>> for Yukicoder {

let mut sess = Session::new(timeout, None, shell)?;

let mut outcome = retrieve_samples(&mut sess, targets)?;
let mut outcome = retrieve_samples(&mut sess, targets, &default_match)?;

if let Some(RetrieveFullTestCases {
credentials: YukicoderRetrieveFullTestCasesCredentials { api_key },
Expand Down Expand Up @@ -315,6 +316,7 @@ fn parse_problem_url(url: &Url) -> anyhow::Result<Either<u64, u64>> {
fn retrieve_samples(
mut sess: impl SessionMut,
targets: YukicoderRetrieveTestCasesTargets,
default_match: &Match,
) -> anyhow::Result<RetrieveTestCasesOutcome> {
let mut outcome = RetrieveTestCasesOutcome { problems: vec![] };

Expand All @@ -323,7 +325,7 @@ fn retrieve_samples(
for problem_no in &problem_nos {
let problem_no = parse_problem_no(problem_no)?;

let (url, test_suite) = retrieve_samples(&mut sess, problem_no)?;
let (url, test_suite) = retrieve_samples(&mut sess, problem_no, default_match)?;
let api::Problem {
problem_id, title, ..
} = sess.get_problem_by_problem_no(problem_no)?;
Expand Down Expand Up @@ -389,7 +391,7 @@ fn retrieve_samples(
}

let api::Problem { no, title, .. } = sess.get_problem_by_problem_id(problem_id)?;
let (url, test_suite) = retrieve_samples(&mut sess, no)?;
let (url, test_suite) = retrieve_samples(&mut sess, no, default_match)?;

outcome.problems.push(RetrieveTestCasesOutcomeProblem {
contest: Some(contest.clone()),
Expand Down Expand Up @@ -419,7 +421,7 @@ fn retrieve_samples(
Either::Right(problem_id) => sess.get_problem_by_problem_id(problem_id)?,
};

let (_, test_suite) = retrieve_samples(&mut sess, no)?;
let (_, test_suite) = retrieve_samples(&mut sess, no, default_match)?;

outcome.problems.push(RetrieveTestCasesOutcomeProblem {
contest: None,
Expand All @@ -439,6 +441,7 @@ fn retrieve_samples(
fn retrieve_samples(
mut sess: impl SessionMut,
problem_no: u64,
default_match: &Match,
) -> anyhow::Result<(Url, TestSuite)> {
let url = url!("/problems/no/{}", problem_no);

Expand All @@ -448,15 +451,15 @@ fn retrieve_samples(
.send()?
.ensure_status(&[200])?
.html()?
.extract_samples()?;
.extract_samples(default_match)?;

Ok((url, test_suite))
}
}

#[ext]
impl Html {
fn extract_samples(&self) -> anyhow::Result<TestSuite> {
fn extract_samples(&self, default_match: &Match) -> anyhow::Result<TestSuite> {
let (timelimit, kind) = self
.select(static_selector!("#content > div"))
.flat_map(|r| r.text())
Expand Down Expand Up @@ -511,7 +514,7 @@ impl Html {
absolute_error,
}
} else {
Match::Lines
default_match.clone()
};

let mut test_suite = BatchTestSuite {
Expand Down
10 changes: 7 additions & 3 deletions snowchains_core/tests/atcoder-retrieve-test-cases.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
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 snowchains_core::{
testsuite::Match,
web::{
Atcoder, AtcoderRetrieveSampleTestCasesCredentials, CookieStorage, ProblemsInContest,
RetrieveTestCases, StatusCodeColor,
},
};
use std::{
fmt,
Expand Down Expand Up @@ -130,6 +133,7 @@ fn test(
credentials: AtcoderRetrieveSampleTestCasesCredentials {
username_and_password: &mut { username_and_password },
},
default_match: Match::Lines,
full: None,
cookie_storage: CookieStorage {
cookie_store: CookieStore::default(),
Expand Down
6 changes: 4 additions & 2 deletions snowchains_core/tests/yukicoder-retrieve-test-cases.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use insta::{assert_debug_snapshot, assert_json_snapshot};
use maplit::btreeset;
use reqwest::{Method, StatusCode};
use snowchains_core::web::{
RetrieveTestCases, StatusCodeColor, Yukicoder, YukicoderRetrieveTestCasesTargets,
use snowchains_core::{
testsuite::Match,
web::{RetrieveTestCases, StatusCodeColor, Yukicoder, YukicoderRetrieveTestCasesTargets},
};
use std::{
fmt,
Expand Down Expand Up @@ -80,6 +81,7 @@ fn test(target: Target) -> anyhow::Result<()> {
}
},
credentials: (),
default_match: Match::Lines,
full: None,
cookie_storage: (),
timeout: TIMEOUT,
Expand Down
5 changes: 4 additions & 1 deletion src/commands/retrieve_testcases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use maplit::btreeset;
use serde::Serialize;
use snowchains_core::{
color_spec,
testsuite::{Additional, BatchTestSuite, TestSuite},
testsuite::{Additional, BatchTestSuite, Match, TestSuite},
web::{
Atcoder, AtcoderRetrieveFullTestCasesCredentials,
AtcoderRetrieveSampleTestCasesCredentials, Codeforces,
Expand Down Expand Up @@ -165,6 +165,7 @@ pub(crate) fn run(
Atcoder::exec(RetrieveTestCases {
targets,
credentials,
default_match: Match::Lines,
full,
cookie_storage,
timeout,
Expand All @@ -189,6 +190,7 @@ pub(crate) fn run(
Codeforces::exec(RetrieveTestCases {
targets,
credentials,
default_match: Match::Lines,
full: None,
cookie_storage,
timeout,
Expand Down Expand Up @@ -223,6 +225,7 @@ pub(crate) fn run(
Yukicoder::exec(RetrieveTestCases {
targets,
credentials: (),
default_match: Match::Lines,
full,
cookie_storage: (),
timeout,
Expand Down

0 comments on commit d276049

Please sign in to comment.