Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plugins/csharp/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use tmc_langs_framework::{
},
error::{CommandError, FileIo},
file_util,
nom::{bytes, character, combinator, sequence, IResult},
nom::{bytes, character, combinator, error::VerboseError, sequence, IResult},
plugin::Language,
zip::ZipArchive,
LanguagePlugin, TmcError,
Expand Down Expand Up @@ -353,7 +353,7 @@ impl LanguagePlugin for CSharpPlugin {
vec![PathBuf::from("test")]
}

fn points_parser(i: &str) -> IResult<&str, &str> {
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
combinator::map(
sequence::delimited(
sequence::tuple((
Expand Down
4 changes: 2 additions & 2 deletions plugins/java/src/ant_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use tmc_langs_framework::{
command::TmcCommand,
domain::{ExerciseDesc, RunResult, StyleValidationResult},
file_util,
nom::IResult,
nom::{error::VerboseError, IResult},
plugin::{Language, LanguagePlugin},
TmcError,
};
Expand Down Expand Up @@ -126,7 +126,7 @@ impl LanguagePlugin for AntPlugin {
Ok(())
}

fn points_parser(i: &str) -> IResult<&str, &str> {
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
Self::java_points_parser(i)
}

Expand Down
8 changes: 4 additions & 4 deletions plugins/java/src/java_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tmc_langs_framework::{
command::TmcCommand,
domain::{ExerciseDesc, RunResult, RunStatus, StyleValidationResult, TestDesc, TestResult},
file_util,
nom::{bytes, character, combinator, sequence, IResult},
nom::{bytes, character, combinator, error::VerboseError, sequence, IResult},
plugin::{Language, LanguagePlugin},
};
use walkdir::WalkDir;
Expand Down Expand Up @@ -254,7 +254,7 @@ pub(crate) trait JavaPlugin: LanguagePlugin {
}

/// Parses @Points("1.1") point annotations.
fn java_points_parser(i: &str) -> IResult<&str, &str> {
fn java_points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
combinator::map(
sequence::delimited(
sequence::tuple((
Expand Down Expand Up @@ -285,7 +285,7 @@ mod test {
use crate::SEPARATOR;

use super::*;
use tmc_langs_framework::{anyhow, TmcError};
use tmc_langs_framework::{anyhow, nom, TmcError};

fn init() {
use log::*;
Expand Down Expand Up @@ -363,7 +363,7 @@ mod test {
unimplemented!()
}

fn points_parser<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
fn points_parser(i: &str) -> IResult<&str, &str, nom::error::VerboseError<&str>> {
Self::java_points_parser(i)
}
}
Expand Down
4 changes: 2 additions & 2 deletions plugins/java/src/maven_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use tmc_langs_framework::{
command::TmcCommand,
domain::{ExerciseDesc, RunResult, StyleValidationResult},
file_util,
nom::IResult,
nom::{error::VerboseError, IResult},
plugin::{Language, LanguagePlugin},
TmcError,
};
Expand Down Expand Up @@ -133,7 +133,7 @@ impl LanguagePlugin for MavenPlugin {
vec![PathBuf::from("src/test")]
}

fn points_parser(i: &str) -> IResult<&str, &str> {
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
Self::java_points_parser(i)
}
}
Expand Down
4 changes: 2 additions & 2 deletions plugins/make/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use tmc_langs_framework::{
domain::{ExerciseDesc, RunResult, RunStatus, TestDesc},
error::{CommandError, FileIo},
file_util,
nom::{bytes, character, combinator, sequence, IResult},
nom::{bytes, character, combinator, error::VerboseError, sequence, IResult},
plugin::LanguagePlugin,
subprocess::PopenError,
zip::ZipArchive,
Expand Down Expand Up @@ -348,7 +348,7 @@ impl LanguagePlugin for MakePlugin {
vec![PathBuf::from("test")]
}

fn points_parser(i: &str) -> IResult<&str, &str> {
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
combinator::map(
sequence::delimited(
sequence::tuple((
Expand Down
29 changes: 26 additions & 3 deletions plugins/notests/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::time::Duration;
use tmc_langs_framework::{
anyhow,
domain::{ExerciseDesc, RunResult, RunStatus, TestDesc, TestResult},
nom::IResult,
nom::{self, error::VerboseError, IResult},
zip::ZipArchive,
LanguagePlugin, StudentFilePolicy, TmcError,
};
Expand Down Expand Up @@ -102,8 +102,9 @@ impl LanguagePlugin for NoTestsPlugin {
vec![PathBuf::from("test")]
}

fn points_parser(_: &str) -> IResult<&str, &str> {
Ok(("", ""))
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
// does not match any characters
nom::combinator::value("", nom::character::complete::one_of(""))(i)
}
}

Expand Down Expand Up @@ -228,4 +229,26 @@ no-tests: false
);
assert!(!NoTestsPlugin::is_exercise_type_correct(temp_dir.path()));
}

#[test]
fn parses_empty() {
init();

let temp = tempfile::tempdir().unwrap();
file_to(&temp, "test/.keep", r#""#);

let points = NoTestsPlugin::get_available_points(temp.path()).unwrap();
assert!(points.is_empty());

let temp = tempfile::tempdir().unwrap();
file_to(
&temp,
"test/.keep",
r#"
"#,
);

let points = NoTestsPlugin::get_available_points(temp.path()).unwrap();
assert!(points.is_empty());
}
}
4 changes: 2 additions & 2 deletions plugins/python3/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use tmc_langs_framework::{
domain::{ExerciseDesc, RunResult, RunStatus, TestDesc, TestResult},
error::CommandError,
file_util,
nom::{branch, bytes, character, combinator, sequence, IResult},
nom::{branch, bytes, character, combinator, error::VerboseError, sequence, IResult},
plugin::LanguagePlugin,
TmcError, TmcProjectYml,
};
Expand Down Expand Up @@ -334,7 +334,7 @@ impl LanguagePlugin for Python3Plugin {
vec![PathBuf::from("test"), PathBuf::from("tmc")]
}

fn points_parser(i: &str) -> IResult<&str, &str> {
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
combinator::map(
sequence::delimited(
sequence::tuple((
Expand Down
91 changes: 72 additions & 19 deletions plugins/r/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use tmc_langs_framework::{
command::TmcCommand,
domain::{ExerciseDesc, RunResult, TestDesc},
file_util,
nom::{bytes, character, combinator, sequence, IResult},
nom::{branch, bytes, character, combinator, error::VerboseError, sequence, IResult},
zip::ZipArchive,
LanguagePlugin, TmcError,
};
Expand Down Expand Up @@ -151,26 +151,44 @@ impl LanguagePlugin for RPlugin {
vec![PathBuf::from("tests")]
}

fn points_parser(i: &str) -> IResult<&str, &str> {
combinator::map(
fn points_parser(i: &str) -> IResult<&str, &str, VerboseError<&str>> {
let test_parser = sequence::delimited(
sequence::tuple((
bytes::complete::tag("test"),
character::complete::multispace0,
character::complete::char('('),
bytes::complete::take_until(","),
bytes::complete::take_until("\""),
)),
sequence::delimited(
character::complete::char('"'),
bytes::complete::is_not("\""),
character::complete::char('"'),
),
sequence::tuple((
character::complete::multispace0,
character::complete::char(')'),
)),
);
let points_for_all_tests_parser = sequence::delimited(
sequence::tuple((
bytes::complete::tag("points_for_all_tests"),
character::complete::multispace0,
character::complete::char('('),
bytes::complete::take_until("\""),
)),
sequence::delimited(
sequence::tuple((
bytes::complete::tag("test"),
character::complete::multispace0,
character::complete::char('('),
bytes::complete::take_until(","),
bytes::complete::take_until("\""),
)),
sequence::delimited(
character::complete::char('"'),
bytes::complete::is_not("\""),
character::complete::char('"'),
),
sequence::tuple((
character::complete::multispace0,
character::complete::char(')'),
)),
character::complete::char('"'),
bytes::complete::is_not("\""),
character::complete::char('"'),
),
sequence::tuple((
character::complete::multispace0,
character::complete::char(')'),
)),
);
combinator::map(
branch::alt((test_parser, points_for_all_tests_parser)),
str::trim,
)(i)
}
Expand Down Expand Up @@ -475,4 +493,39 @@ test("sample", c("r1.1"), {
"#;
assert_eq!(RPlugin::points_parser(target).unwrap().1, "W1A.1.2");
}

#[test]
fn parsing_regression_test() {
init();

let temp = tempfile::tempdir().unwrap();
// a file like this used to cause an error before for some reason...
file_to(
&temp,
"tests/testthat/testExercise.R",
r#"library('testthat')
"#,
);

let _points = RPlugin::get_available_points(temp.path()).unwrap();
}

#[test]
fn parses_points_for_all_tests() {
init();

let temp = tempfile::tempdir().unwrap();
file_to(
&temp,
"tests/testthat/testExercise.R",
r#"
something
points_for_all_tests(c("r1"))
etc
"#,
);

let points = RPlugin::get_available_points(temp.path()).unwrap();
assert_eq!(points, &["r1"]);
}
}
2 changes: 1 addition & 1 deletion tmc-langs-framework/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ serde_yaml = "0.8"
zip = "0.5"
schemars = "0.8"
once_cell = "1"
nom = "6"
nom = { version = "6", features = ["alloc"] }
funty = "=1.1.0" # temporary workaround, remove later
subprocess = "0.2"
tempfile = "3"
Expand Down
4 changes: 2 additions & 2 deletions tmc-langs-framework/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ pub enum TmcError {
Canonicalize(PathBuf, #[source] std::io::Error),
#[error("File {0} not in given project root {1}")]
FileNotInProject(PathBuf, PathBuf),
#[error("Error while parsing available points: {0}")]
PointParse(String),
#[error("Error while parsing available points from {0}")]
PointParse(PathBuf, #[source] nom::error::VerboseError<String>),

#[error("Path {0} contained no file name")]
NoFileName(PathBuf),
Expand Down
Loading