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

Display available tutorials #234

Merged
merged 22 commits into from
Jun 6, 2019
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
71cc6bb
add an available tutorials method
schloerke May 7, 2019
8510a3d
return unique tutorials only
schloerke May 7, 2019
ec6d8fa
Tests for available_tutorials
schloerke May 7, 2019
5ac6ae2
check if package exists
schloerke May 15, 2019
9c057c9
make available tutorials invisible when returning from run_tutorial
schloerke May 15, 2019
e666036
add `stop.` which equals `stop(..., call. = FALSE)`
schloerke May 15, 2019
664d81c
add tests
schloerke May 15, 2019
bc2f682
document
schloerke May 15, 2019
48b8b95
Merge branch 'master' into available_tutorials
schloerke May 15, 2019
5def57c
add close matching if within 3 letters
schloerke May 29, 2019
7e38871
import adist from utils
schloerke May 29, 2019
c27e503
added new news item and rearranged the news order
schloerke May 29, 2019
7a143d1
merge news
schloerke May 29, 2019
f4bf3a5
Merge branch 'master' into available_tutorials
schloerke May 29, 2019
f8e3f80
ignore case within adist to give best match
schloerke May 29, 2019
c6d0e87
give slidy a title
schloerke May 29, 2019
eb13ea7
comment why using 'missing'
schloerke May 29, 2019
65de1ea
add an example in run_tutorial. Also display all available learnr tu…
schloerke May 29, 2019
71817df
use NULL default values for run_tutorial to avoid "missing" issues
schloerke May 29, 2019
323884b
extract out available_tutorial methods to a single file. Add formatti…
schloerke May 29, 2019
d3537dd
cleaner error formatting
schloerke May 29, 2019
df9faf3
minor code feedback
schloerke Jun 6, 2019
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
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ S3method(mutate_tags,logical)
S3method(mutate_tags,numeric)
S3method(mutate_tags,shiny.tag)
export(answer)
export(available_tutorials)
export(duplicate_env)
export(filesystem_storage)
export(initialize_tutorial)
Expand Down Expand Up @@ -60,5 +61,6 @@ importFrom(shiny,reactive)
importFrom(shiny,reactiveValues)
importFrom(shiny,req)
importFrom(stats,runif)
importFrom(utils,adist)
importFrom(utils,getFromNamespace)
importFrom(withr,with_envvar)
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ learnr 0.10.0 (unreleased)

* Question width will expand to the container width. ([#222](https://github.com/rstudio/learnr/pull/222))

* Available tutorial names will be displayed when no `name` parameter or an incorrect `name` is provided to `run_tutorial()`. ([#234](https://github.com/rstudio/learnr/pull/234))

## Bug fixes

* Fixed a spurious console warning when running exercises using Pandoc 2.0. ([#154](https://github.com/rstudio/learnr/issues/154))



learnr 0.9.2
===========

Expand Down
60 changes: 57 additions & 3 deletions R/run.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,48 @@
#' the .Rmd file must exist).
#'
#' @seealso \code{\link{safe}}
#' @rdname run_tutorial
#' @importFrom utils adist
#' @export
run_tutorial <- function(name, package, shiny_args = NULL) {

possible_tutorials <- available_tutorials(package)
pkg_tutorials <- paste0(
"Available \"", package, "\" tutorials: ", paste0(paste0("\"", possible_tutorials, "\""), collapse = ", ")
)

if (missing(name)) {
message(pkg_tutorials)
return(invisible(possible_tutorials))
}

# get path to tutorial
tutorial_path <- system.file("tutorials", name, package = package)

# validate that it's a direcotry
if (!utils::file_test("-d", tutorial_path))
stop("Tutorial ", name, " was not found in the ", package, " package.")
if (!utils::file_test("-d", tutorial_path)) {
firstlinesep <- "\t"
linesep <- "\n\t"
msg <- paste0("Tutorial \"", name, "\" was not found in the \"", package, "\" package.")
# if any tutorial names are _close_ tell the user
adist_vals <- adist(possible_tutorials, name)
schloerke marked this conversation as resolved.
Show resolved Hide resolved
if (any(adist_vals <= 3)) {
best_match <- possible_tutorials[which.min(adist_vals)]
msg <- paste0(
msg, linesep,
"Did you mean \"", best_match, "\"?"
)
}
stop.(firstlinesep, msg, linesep, pkg_tutorials)
schloerke marked this conversation as resolved.
Show resolved Hide resolved
}

# provide launch_browser if it's not specified in the shiny_args
if (is.null(shiny_args))
shiny_args <- list()
if (is.null(shiny_args$launch.browser)) {
shiny_args$launch.browser <- (
interactive() ||
identical(Sys.getenv("LEARNR_INTERACTIVE", "0"), "1")
identical(Sys.getenv("LEARNR_INTERACTIVE", "0"), "1")
)
}

Expand All @@ -45,6 +70,35 @@ run_tutorial <- function(name, package, shiny_args = NULL) {
})
}

#' @rdname run_tutorial
#' @export
available_tutorials <- function(package) {

if (!file.exists(
system.file(package = package)
)) {
stop.("No package found with name: \"", package, "\"")
schloerke marked this conversation as resolved.
Show resolved Hide resolved
}

tutorials_dir <- system.file("tutorials", package = package)
if (!file.exists(tutorials_dir)) {
stop.("No tutorials found for package: \"", package, "\"")
}

tutorial_folders <- list.dirs(tutorials_dir, full.names = TRUE, recursive = FALSE)
names(tutorial_folders) <- basename(tutorial_folders)
has_rmd <- vapply(tutorial_folders, FUN.VALUE = logical(1), function(tut_dir) {
length(dir(tut_dir, pattern = "\\.Rmd$", recursive = FALSE)) > 0
})
if (all(!has_rmd)) {
stop.("No tutorial .Rmd files found for package: \"", package, "\"")
}

tutorial_names <- tutorial_folders[has_rmd]
unique(names(tutorial_names))
}



#' Safe R CMD environment
#'
Expand Down
4 changes: 4 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ is_localhost <- function(location) {
FALSE
}

stop. <- function(...) {
stop(..., call. = FALSE)
}


#' Create a duplicate of an environment
#'
Expand Down
3 changes: 3 additions & 0 deletions man/run_tutorial.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions tests/testthat/test-available-tutorials.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

context("available tutorials")

test_that("Tutorial names are retrieved", {

expect_error(available_tutorials("not a package"), "No package found")
expect_error(available_tutorials("base"), "No tutorials found")
expect_true("hello" %in% available_tutorials("learnr"))
expect_true("hello" %in% suppressMessages(run_tutorial(package = "learnr")))

expect_error(run_tutorial("helloo", package = "learnr"), "\"hello\"")
expect_error(run_tutorial("doesn't exist", package = "learnr"), "Available ")
expect_message(run_tutorial(package = "learnr"), "Available ")

})