Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provides instructions on parse error caused by code scaffolding in learnr tutorial #153

Merged
merged 11 commits into from Dec 8, 2020
48 changes: 32 additions & 16 deletions R/grade_learnr.R
Expand Up @@ -85,22 +85,7 @@ grade_learnr_ <- function(label = NULL,
user_code <- tryCatch(
parse(text = user_code %||% ""),
error = function(e) {
parse_checker <- getOption(
"exercise.parse.error",
function(...) {
graded(
correct = FALSE,
message = paste(
"Uh oh, the R code produced a syntax error:",
conditionMessage(e),
"\nCheck that you have closed every \", ', (, and { ",
"with a matching \", ', ), and }. Also look for missing ",
"commas. R cannot determine how to turn your text into ",
"a complete command."
)
)
}
)
parse_checker <- getOption("exercise.parse.error", grade_learnr_parse_error)
# check that parse_checker is a function with proper args
do.call(parse_checker, list(parse_error = e, learnr_args = learnr_args))
}
Expand Down Expand Up @@ -186,6 +171,37 @@ grade_learnr_ <- function(label = NULL,
)
}

grade_learnr_parse_error <- function(parse_error, learnr_args) {
# Code scaffolding in exercise code will cause parse errors, so first check
# for blanks. We consider a blank to be 3+ "_" characters.
n_blanks <- sum(vapply(
gregexpr("_{3,}", learnr_args$user_code),
function(x) sum(x > 0),
integer(1)
))
msg <- if (n_blanks > 0) {
paste0(
"The exercise contains ",
if (n_blanks == 1L) {
"1 blank"
} else {
paste(n_blanks, "blanks")
},
". Please replace the '____' with valid R code."
)
} else {
paste(
"Uh oh, the R code produced a syntax error:",
conditionMessage(parse_error),
"\nCheck that you have closed every \", ', (, and { ",
"with a matching \", ', ), and }. Also look for missing ",
"commas. R cannot determine how to turn your text into ",
"a complete command."
)
}
schloerke marked this conversation as resolved.
Show resolved Hide resolved
graded(correct = FALSE, message = msg)
}


#' @rdname grade_learnr
#' @export
Expand Down
9 changes: 9 additions & 0 deletions tests/testthat/test_grade_learnr.R
Expand Up @@ -83,6 +83,15 @@ test_that("Grade learnr check_code", {
expect_false(parse_error$correct)
expect_true(parse_error$type == "error")

# Code scaffolding produces informative parsing error message
one_blank <- grade_learnr(user_code = "____(mtcars, cyl)")
expect_false(one_blank$correct)
expect_true(grepl("1 blank", one_blank$message))

three_blanks <- grade_learnr(user_code = "________(___, ____)")
expect_false(three_blanks$correct)
expect_true(grepl("3 blanks", three_blanks$message))

# Can customize the feedback through an exercise.parse.error function
parse_error_func <- function(parse_error, learnr_args) {
graded(
Expand Down