Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
..Rcheck
*.Rcheck
*.tar.gz
.DS_Store
src/*.o
src/*.so
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: testthatsomemore
Title: A mocking, stubbing, and file testing framework extending testthat
Version: 0.2.6
Version: 0.2.7
Maintainer: Robert Krzyzanowski <technoguyrob@gmail.com>
Authors@R: c(person("Robert", "Krzyzanowski",
email = "technoguyrob@gmail.com", role = c("aut", "cre")))
Expand All @@ -24,4 +24,4 @@ License: MIT + file LICENSE
LazyData: true
URL: http://github.com/robertzk/testthatsomemore
BugReports: https://github.com/robertzk/testthatsomemore/issues
RoxygenNote: 5.0.1
RoxygenNote: 5.0.0
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
export("stub<-")
export(assert)
export(create_file_structure)
export(duplicate)
export(expect_is_directory)
export(expect_is_file)
export(is.directory)
Expand All @@ -14,3 +15,4 @@ export(touch)
export(within_file_structure)
import(testthat)
importFrom(crayon,yellow)
useDynLib(testthatsomemore,duplicate_testthatsomemore_)
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Version 0.2.7

* Added expect_called helper function.

# Version 0.2.6

* Added mock_httr_response for mocking httr response objects.
Expand Down
17 changes: 17 additions & 0 deletions R/duplicate.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#' Duplicate a function. Returns a carbon copy of the original, so that original
#' can be modified safely.
#'
#' @param x function.
#' @examples
#' \dontrun{
#' fn <- function(x) cat(x, "\n")
#' fn2 <- duplicate(fn)
#' fn <- function(x) cat(x, "woof","\n")
#' fn("hello") # hellowoof
#' fn2("hello") # hello
#' }
#' @export
#' @useDynLib testthatsomemore duplicate_testthatsomemore_
duplicate <- function(x) {
.Call(duplicate_testthatsomemore_, x)
}
42 changes: 42 additions & 0 deletions R/expect_called.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#' Expect that a function was called while executing an expression.
#'
#' @param fn function. The function that was expected to get called. If not
#' specified with \code{::}, package_name param must be specified.
#' @param expr expression. The expression to execute.
#' @param package_name string. The package where fn lives. If not specified, fn must
#' be package_name::fn.
#' @param was_called logical. If \code{FALSE}, negate the meaning: \code{fn}
#' should \emph{not} have been called. By default \code{TRUE}.
#' @return invisible \code{TRUE}.
#' @examples \dontrun{
#' expect_called(base::print, print("Hello")) # Will pass
#' expect_called(print, print("Hello"), "base") # Will pass
#' expect_called(base::print, cat("Hello")) # Will fail
#' expect_called(base::print, cat("Hello"), was_called = FALSE) # Will pass
#' }
expect_called <- function(fn, expr, package_name, was_called = TRUE) {
fn <- substitute(fn)
if (is.call(fn) && identical(as.character(fn[[1]]), "not")) {
fn <- fn[[2]]
was_called <- FALSE
}
# Turn foo into package_name::foo
if (is.name(substitute(fn))) fn <- bquote(getFromNamespace(.(deparse(fn)), .(package_name)))
else fn <- as.call(list(quote(getFromNamespace), as.character(fn[[3]]), as.character(fn[[2]])))

grab <- function(i) as.character(as.list(fn)[[i]])

copy_of_fn <- duplicate(eval(fn))
env <- list2env(list(called = 0), parent = emptyenv())

mocked_fn <- function(...) {
env$called <- env$called + 1
copy_of_fn(...)
}

result <- testthatsomemore::package_stub(grab(3), grab(2), mocked_fn, force(expr))
expect_identical(was_called, as.logical(env$called))

invisible(TRUE)
}

26 changes: 26 additions & 0 deletions man/duplicate.Rd

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

35 changes: 35 additions & 0 deletions man/expect_called.Rd

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

9 changes: 9 additions & 0 deletions src/duplicate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//shamelessly ripped off from @jimhester
#define USE_RINTERNALS
#include <R.h>
#include <Rdefines.h>
#include <R_ext/Error.h>

SEXP duplicate_testthatsomemore_(SEXP x) {
return duplicate(x);
}
7 changes: 7 additions & 0 deletions tests/testthat/test-duplicate.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
context("duplicate")

test_that('it duplicates a function', {
fn <- function(x) cat(x, "\n")
fn_copy <- duplicate(fn)
expect_equal(fn, fn_copy)
})
31 changes: 31 additions & 0 deletions tests/testthat/test-expect_called.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
context('expect_called')


test_that('it finds called function', {
f <- function() sum(2, 2)
expect_true(expect_called(base::sum, f()))
})

test_that('it detects function was not called', {
f <- function() 10
expect_true(expect_called(base::sum, f(), was_called = FALSE ))
})

test_that('Package setting works', {
f <- function() sum(1, 2)
expect_true(expect_called(sum, f(), "base"))
})

# neither test_that nor describe wrappers work here?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danilito19 What was the problem?

# test_that('it detects errors when function is expected but actually not called', {
# f <- function() 10
# expect_error(
# expect_called(base::sum, f() ),
# "is not identical"
# )
# })





4 changes: 3 additions & 1 deletion tests/testthat/test-pretend_now_is.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ describe("pretend_now_is", {
test_that("it can pretend it's 5 seconds ago", {
now <- Sys.time()
five_s_ago <- now - as.difftime(5, units = "secs")
pretend_now_is("5 seconds ago", expect_equal(Sys.time(), five_s_ago))
pretend_now_is("5 seconds ago", {
expect_equal(as.Date(Sys.time()), as.Date(five_s_ago))
})
})

test_that("it can pretend Sys.Date is different", {
Expand Down