|
| 1 | +#' Mock a sequence of output from a function |
| 2 | +#' |
| 3 | +#' Specify multiple return values for mocking |
| 4 | +#' |
| 5 | +#' @param ... <[`dynamic-dots`][rlang::dyn-dots]> Values to return in sequence. |
| 6 | +#' @param recycle whether to recycle. If `TRUE`, once all values have been returned, |
| 7 | +#' they will be returned again in sequence. |
| 8 | +#' |
| 9 | +#' @return A function that you can use within `local_mocked_bindings()` and |
| 10 | +#' `with_mocked_bindings()` |
| 11 | +#' @export |
| 12 | +#' |
| 13 | +#' @examples |
| 14 | +#' # inside local_mocked_bindings() |
| 15 | +#' \dontrun{ |
| 16 | +#' local_mocked_bindings(readline = mock_output_sequence("3", "This is a note", "n")) |
| 17 | +#' } |
| 18 | +#' # for understanding |
| 19 | +#' mocked_sequence <- mock_output_sequence("3", "This is a note", "n") |
| 20 | +#' mocked_sequence() |
| 21 | +#' mocked_sequence() |
| 22 | +#' mocked_sequence() |
| 23 | +#' try(mocked_sequence()) |
| 24 | +#' recycled_mocked_sequence <- mock_output_sequence( |
| 25 | +#' "3", "This is a note", "n", |
| 26 | +#' recycle = TRUE |
| 27 | +#' ) |
| 28 | +#' recycled_mocked_sequence() |
| 29 | +#' recycled_mocked_sequence() |
| 30 | +#' recycled_mocked_sequence() |
| 31 | +#' recycled_mocked_sequence() |
| 32 | +#' @family mocking |
| 33 | +mock_output_sequence <- function(..., recycle = FALSE) { |
| 34 | + values <- rlang::list2(...) |
| 35 | + i <- 1 |
| 36 | + function(...) { |
| 37 | + if (i > length(values) && !recycle) { |
| 38 | + cli::cli_abort(c( |
| 39 | + "Can't find value for {i}th iteration.", |
| 40 | + i = "{.arg ...} has only {length(values)} values.", |
| 41 | + i = "You can set {.arg recycle} to {.code TRUE}." |
| 42 | + )) |
| 43 | + } |
| 44 | + index <- (i - 1) %% length(values) + 1 |
| 45 | + value <- rep_len(values, length.out = index)[[index]] |
| 46 | + i <<- i + 1 |
| 47 | + value |
| 48 | + } |
| 49 | +} |
0 commit comments