File: expectations.R

package info (click to toggle)
r-cran-mockery 0.4.1.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 168 kB
  • sloc: sh: 13; makefile: 2
file content (130 lines) | stat: -rw-r--r-- 3,200 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

#' Expectation: does the given call match the expected?
#'
#' Together with \code{\link{mock}} can be used to verify whether the
#' call expression (\code{\link{expect_call}}) and/or argument values
#' (\code{\link{expect_args}}) match the expected.
#'
#' With \code{expect_called} you can check how many times has the mock
#' object been called.
#'
#' @param mock_object A \code{\link{mock}} object.
#' @param n Call number or total number of calls.
#' @param expected_call Expected call expression; will be compared unevaluated.
#' @param ... Arguments as passed in a call.
#'
#' @examples
#' library(testthat)
#'
#' # expect call expression (signature)
#' m <- mock()
#' with_mock(summary = m, summary(iris))
#'
#' # it has been called once
#' expect_called(m, 1)
#'
#' # the first (and only) call's arguments matches summary(iris)
#' expect_call(m, 1, summary(iris))
#'
#' # expect argument value
#' m <- mock()
#' a <- iris
#' with_mock(summary = m, summary(object = a))
#' expect_args(m, 1, object = a)
#' # is an equivalent to ...
#' expect_equal(mock_args(m)[[1]], list(object = a))
#'
#' @name call-expectations
#'
NULL



#' @export
#' @rdname call-expectations
#'
#' @importFrom testthat expect
expect_call <- function (mock_object, n, expected_call) {
  stopifnot(is_mock(mock_object))

  expect(
    0 < n && n <= length(mock_object),
    sprintf("call number %s not found in mock object", toString(n))
  )

  expected_call <- substitute(expected_call)
  mocked_call <- mock_calls(mock_object)[[n]]

  format_call <- function (x) paste(trimws(deparse(x)), collapse = ' ')
  
  expect(
    identical(mocked_call, expected_call),
    sprintf("expected call %s does not mach actual call %s.",
            format_call(expected_call), format_call(mocked_call))
  )

  invisible(TRUE)
}


#' @export
#' @rdname call-expectations
#'
#' @importFrom testthat expect expect_equal
expect_args <- function (mock_object, n, ...)
{
  stopifnot(is_mock(mock_object))

  expect(
    0 < n && n <= length(mock_object),
    sprintf("arguments list number %s not found in mock object", toString(n))
  )

  expected_args <- list(...)
  actual_args   <- mock_args(mock_object)[[n]]
  
  expect_equal(length(actual_args), length(expected_args),
               info = 'number of expected args does not match the actual')
  
  for (i in seq_along(actual_args)) {
    expect_equal(
      actual_args[[i]],
      expected_args[[i]],
      label = paste(ordinal(i), 'actual argument'),
      expected.label = paste(ordinal(i), 'expected argument')
    ) 
  }

  invisible(TRUE)
}


ordinal <- function (x) 
{
  stopifnot(is.integer(x), x > 0, length(x) == 1)
  if (x %in% 11:13)
    return(paste0(x, 'th'))

  as_string  <- as.character(x)
  last_digit <- substring(as_string, nchar(as_string))
  suffix <- switch(last_digit,
         `1` = 'st',
         `2` = 'nd',
         `3` = 'rd',
               'th')
  paste0(as_string, suffix)
}


#' @export
#' @rdname call-expectations
expect_called <- function (mock_object, n)
{
  stopifnot(is_mock(mock_object))

  expect(
    length(mock_object) == n,
    sprintf("mock object has not been called %s time%s", toString(n),
            (if(n>1) "s" else ""))
  )
}