}}
@@ -113,6 +132,8 @@ user. Always \code{NULL} for a \code{MockShinySesion}.}
\item \href{#method-MockShinySession-onSessionEnded}{\code{MockShinySession$onSessionEnded()}}
\item \href{#method-MockShinySession-registerDownload}{\code{MockShinySession$registerDownload()}}
\item \href{#method-MockShinySession-getCurrentOutputInfo}{\code{MockShinySession$getCurrentOutputInfo()}}
+\item \href{#method-MockShinySession-sendInputMessage}{\code{MockShinySession$sendInputMessage()}}
+\item \href{#method-MockShinySession-verifyInputMessage}{\code{MockShinySession$verifyInputMessage()}}
\item \href{#method-MockShinySession-clone}{\code{MockShinySession$clone()}}
}
}
@@ -610,8 +631,88 @@ executed.
\subsection{Returns}{
A list with with the \code{name} of the output. If no output is
currently being executed, this will return \code{NULL}.
-output, or \code{NULL} if no output is currently executing.
}
+}
+\if{html}{\out{
}}
+\if{html}{\out{
}}
+\if{latex}{\out{\hypertarget{method-MockShinySession-sendInputMessage}{}}}
+\subsection{Method \code{sendInputMessage()}}{
+Mocks a \code{session$sendInputMessage}-call
+that can be later verified.
+\subsection{Usage}{
+\if{html}{\out{
}}\preformatted{MockShinySession$sendInputMessage(inputId, message)}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{
}}
+\describe{
+\item{\code{inputId, message}}{See \code{sendInputMessage} in \link{session}.}
+}
+\if{html}{\out{
}}
+}
+}
+\if{html}{\out{
}}
+\if{html}{\out{
}}
+\if{latex}{\out{\hypertarget{method-MockShinySession-verifyInputMessage}{}}}
+\subsection{Method \code{verifyInputMessage()}}{
+Verifies that a call to \code{session$sendInputMessage} has been performed.
+
+Use either simple expectations, e.g. \code{expect_equal(., "some value")},
+or functions, \code{function(x) is.list(x)} or
+\code{function(x) expect_equal(x, list(1))}.
+
+For simple expectations, the sent message is accessed with \code{.}.
+
+For functions, they are called with the sent message as first argument.
+If any of the expressions in the function throws an error, \code{verifyInputMessage}
+fails.
+
+For both functions and expectations, their returned value must be
+\code{NULL} or pass \code{\link{isTruthy}} for the assertion to succeed.
+
+NB! testthat's \verb{expect_*}-functions, when the expectations succeeds,
+returns the tested value. I.e. if testing for any of the values on the
+list in \code{\link{isTruthy}} (\code{FALSE}, \code{""}, \code{vector(0)}, etc.), \code{verifyInputMessage}
+will fail if results not properly wrapped.
+\subsection{Usage}{
+\if{html}{\out{
}}\preformatted{MockShinySession$verifyInputMessage(inputId, ..., env = rlang::caller_env())}\if{html}{\out{
}}
+}
+
+\subsection{Arguments}{
+\if{html}{\out{
}}
+\describe{
+\item{\code{inputId}}{Expected inputId and message of the
+last call to \code{session$sendInputMessage}.}
+
+\item{\code{...}}{Assertions to test against.}
+
+\item{\code{env}}{(advanced use only) the environment in which to evaluate
+\code{...} assertions.
+output, or \code{NULL} if no output is currently executing.}
+}
+\if{html}{\out{
}}
+}
+\subsection{Examples}{
+\if{html}{\out{
}}
+\preformatted{session <- MockShinySession$new()
+session$sendInputMessage("foo", "")
+session$sendInputMessage("bar", list(value=2, add=TRUE))
+session$verifyInputMessage("foo", . == "")
+\dontrun{
+ # This should be wrapped in an if (requireNamespace("testthat)),
+ # but expect_equal was still now found?!
+ session$verifyInputMessage("bar", expect_equal(., list(value=2, add=TRUE)))
+
+ # Will fail, as `expect_equal` returns the value, which
+ # in this case is not truthy.
+ session$verifyInputMessage("foo", expect_equal(., ""))
+}
+
+}
+\if{html}{\out{
}}
+
+}
+
}
\if{html}{\out{
}}
\if{html}{\out{
}}
diff --git a/tests/testthat/test-mock-session.R b/tests/testthat/test-mock-session.R
index 8a34696b58..5272933caf 100644
--- a/tests/testthat/test-mock-session.R
+++ b/tests/testthat/test-mock-session.R
@@ -245,7 +245,51 @@ test_that("session supports sendBinaryMessage", {
test_that("session supports sendInputMessage", {
session <- MockShinySession$new()
session$sendInputMessage(inputId=1, message=2)
- expect_true(TRUE) # testthat insists that every test must have an expectation
+ session$sendInputMessage(inputId="foo", message=list(bar=1, add=TRUE))
+ session$verifyInputMessage(1, expect_equal(., 2))
+ session$verifyInputMessage(1, function(x) {
+ expect_type(x, "double")
+ expect_equal(x, 2)
+ })
+ session$verifyInputMessage("foo", expect_true(.$add), expect_equal(.$bar, 1))
+})
+
+test_that("verifyInputMessage is itself enough for a `test_that`", {
+ session <- MockShinySession$new()
+ session$sendInputMessage(inputId=1, message=2)
+ session$verifyInputMessage(1, . == 2)
+})
+
+test_that("session supports failing verifyInputMessage", {
+ session <- MockShinySession$new()
+ expect_failure(
+ session$verifyInputMessage(1, expect_equal(., 1)),
+ message = "session$sendInputMessage(inputId=\"1\") has not been called.",
+ fixed = TRUE
+ )
+ session$sendInputMessage(inputId=1, message=2)
+ expect_success(session$verifyInputMessage(1, expect_equal(., 2)))
+ expect_failure(
+ session$verifyInputMessage(1, expect_equal(., 1)),
+ message = "`.` (`actual`) not equal to 1 (`expected`)",
+ fixed = TRUE
+ )
+ expect_failure(
+ session$verifyInputMessage(1, function(x) expect_equal(x, 1)),
+ message = "`x` (`actual`) not equal to 1 (`expected`)",
+ fixed = TRUE
+ )
+ expect_failure(
+ session$verifyInputMessage(1, . == 1),
+ message = ". == 1 is not TRUE",
+ fixed = TRUE
+ )
+ expect_failure(
+ session$verifyInputMessage(1, function(x) x == 1),
+ message = "function(x) x == 1 is not TRUE",
+ fixed = TRUE
+ )
+
})
test_that("session supports setBookmarkExclude", {
diff --git a/tests/testthat/test-update-input.R b/tests/testthat/test-update-input.R
index 369db4efc1..b236f88558 100644
--- a/tests/testthat/test-update-input.R
+++ b/tests/testthat/test-update-input.R
@@ -1,36 +1,19 @@
test_that("Radio buttons and checkboxes work with modules", {
- createModuleSession <- function(moduleId) {
- session <- as.environment(list(
- ns = NS(moduleId),
- sendInputMessage = function(inputId, message) {
- session$lastInputMessage = list(id = inputId, message = message)
- }
- ))
- class(session) <- "ShinySession"
- session
- }
-
- sessA <- createModuleSession("modA")
-
- updateRadioButtons(sessA, "test1", label = "Label", choices = letters[1:5])
- resultA <- sessA$lastInputMessage
-
- expect_equal("test1", resultA$id)
- expect_equal("Label", resultA$message$label)
- expect_equal("a", resultA$message$value)
- expect_true(grepl('"modA-test1"', resultA$message$options))
- expect_false(grepl('"test1"', resultA$message$options))
-
-
- sessB <- createModuleSession("modB")
-
- updateCheckboxGroupInput(sessB, "test2", label = "Label", choices = LETTERS[1:5])
- resultB <- sessB$lastInputMessage
-
- expect_equal("test2", resultB$id)
- expect_equal("Label", resultB$message$label)
- expect_null(resultB$message$value)
- expect_true(grepl('"modB-test2"', resultB$message$options))
- expect_false(grepl('"test2"', resultB$message$options))
-
+ session <- MockShinySession$new()
+
+ updateRadioButtons(session, "test1", label = "Label", choices = letters[1:5])
+ session$verifyInputMessage("test1",
+ expect_equal(.$label, "Label"),
+ expect_equal(.$value, "a"),
+ expect_true(grepl('"mock-session-test1"', .$options)),
+ !expect_false(grepl('"test1"', .$options)) ## negate returned FALSE from expect_false
+ )
+
+ updateCheckboxGroupInput(session, "test2", label = "Label", choices = LETTERS[1:5])
+ session$verifyInputMessage("test2",
+ expect_equal(.$label, "Label"),
+ expect_null(.$value),
+ expect_true(grepl('"mock-session-test2"', .$options)),
+ !expect_false(grepl('"test2"', .$options))
+ )
})