|
| 1 | +#' @importFrom rlang abort |
| 2 | +make_hook <- function(name) { |
| 3 | + function(hook) { |
| 4 | + if (length(formals(hook)) != 2) { |
| 5 | + abort( |
| 6 | + message = "Hook must have two arguments.", |
| 7 | + body = "The first argument is the context and the second is the scenario name." |
| 8 | + ) |
| 9 | + } |
| 10 | + register_hook(hook, name) |
| 11 | + invisible(hook) |
| 12 | + } |
| 13 | +} |
| 14 | + |
| 15 | +#' Hooks |
| 16 | +#' |
| 17 | +#' Hooks are functions that are run before or after a scenario. |
| 18 | +#' |
| 19 | +#' You can define them alongside steps definitions. |
| 20 | +#' |
| 21 | +#' If you want to run a hook only before or after a specific scenario, use it's name to execute hook only for this scenario. |
| 22 | +#' |
| 23 | +#' @param hook A function that will be run. The function first argument is context and the scenario name is the second argument. |
| 24 | + |
| 25 | +#' @examples |
| 26 | +#' \dontrun{ |
| 27 | +#' before(function(context, scenario_name) { |
| 28 | +#' context$session <- selenider::selenider_session() |
| 29 | +#' }) |
| 30 | +#' |
| 31 | +#' after(function(context, scenario_name) { |
| 32 | +#' selenider::close_session(context$session) |
| 33 | +#' }) |
| 34 | +#' |
| 35 | +#' after(function(context, scenario_name) { |
| 36 | +#' if (scenario_name == "Playing one round of the game") { |
| 37 | +#' context$game$close() |
| 38 | +#' } |
| 39 | +#' }) |
| 40 | +#' } |
| 41 | +#' @md |
| 42 | +#' @name hook |
| 43 | +NULL |
| 44 | + |
| 45 | +#' @rdname hook |
| 46 | +#' @export |
| 47 | +before <- make_hook("before") |
| 48 | + |
| 49 | +#' @rdname hook |
| 50 | +#' @export |
| 51 | +after <- make_hook("after") |
| 52 | + |
| 53 | +#' @importFrom rlang list2 |
| 54 | +.hooks <- function(...) { |
| 55 | + structure(list2(...), class = "hooks") |
| 56 | +} |
| 57 | + |
| 58 | +#' @importFrom rlang `:=` arg_match abort |
| 59 | +#' @importFrom checkmate test_subset |
| 60 | +#' @importFrom glue glue |
| 61 | +register_hook <- function( |
| 62 | + hook, |
| 63 | + name = c("before", "after") |
| 64 | +) { |
| 65 | + arg_match(name) |
| 66 | + hooks <- getOption(".cucumber_hooks", default = .hooks()) |
| 67 | + if (test_subset(name, names(hooks))) { |
| 68 | + abort( |
| 69 | + message = glue("Hook '{name}' already registered."), |
| 70 | + body = "A hook can only be registered once." |
| 71 | + ) |
| 72 | + } |
| 73 | + hooks <- .hooks(!!name := hook) |
| 74 | + options(.cucumber_hooks = hooks) |
| 75 | + invisible(hooks) |
| 76 | +} |
| 77 | + |
| 78 | +#' @importFrom purrr pluck |
| 79 | +get_hook <- function(hooks = get_hooks(), name) { |
| 80 | + pluck(hooks, name, .default = function(...) { }) |
| 81 | +} |
| 82 | + |
| 83 | +clear_hooks <- function() { |
| 84 | + options(.cucumber_hooks = .hooks()) |
| 85 | +} |
| 86 | + |
| 87 | +get_hooks <- function() { |
| 88 | + getOption(".cucumber_hooks", default = .hooks()) |
| 89 | +} |
0 commit comments