test_that("action in formula notation", { do <- function() { dx1 <- deferred$new(function(resolve) resolve(TRUE))$ then(function(.) expect_true(.)) dx2 <- deferred$new(function(resolve) stop("oops"))$ catch(error = function(.) expect_match(conditionMessage(.), "oops")) dx3 <- deferred$new(function(resolve) if (TRUE) resolve(TRUE) else stop("oops"))$ then(function(.) expect_true(.)) dx4 <- deferred$new(function(resolve) if (FALSE) resolve(TRUE) else stop("oops"))$ catch(error = function(.) expect_match(conditionMessage(.), "oops")) when_all(dx1, dx2, dx3, dx4) } synchronise(do()) }) test_that("on_fulfilled / on_rejected without arguments", { do <- async(function() { dx1 <- deferred$new(function(resolve) resolve(TRUE))$ then(function() "OK")$ then(function(.) expect_equal(., "OK")) dx2 <- deferred$new(function(resolve) resolve(TRUE))$ then(function() stop("oops"))$ catch(error = function(.) expect_match(conditionMessage(.), "oops")) dx3 <- deferred$new(function(resolve) resolve(TRUE))$ then(function() stop("ooops"))$ catch(error = function(.) "aaah")$ then(function(.) expect_equal(., "aaah")) when_all(dx1, dx2, dx3) }) synchronise(do()) }) test_that("parent pointer", { ## Parent pointer is added when the deferred is created, but it ## is removed, once the promise is resolved do <- function() { d1 <- delay(1/1000) d2 <- d1$then(force) d3 <- d2$then(function() expect_true(is.null(get_private(d2)$parent))) expect_equal(length(get_private(d2)$parent), 0) d3 } synchronise(do()) }) test_that("unused computation is never created", { called1 <- called2 <- FALSE do <- function() { d1 <- deferred$new( function(resolve, reject) { called1 <<- TRUE; resolve("foo") }) d2 <- deferred$new( function(resolve, reject) { called2 <<- TRUE; resolve("bar") }) d2 } expect_equal(synchronise(do()), "bar") expect_false(called1) expect_true(called2) }) test_that("replacing promises does not leak", { loop <- function(limit = 5) { limit n <- 1 x <- list() do <- function() { x <<- append(x, list(async_list())) if (n < limit) { n <<- n + 1 delay(0)$then(do) } else { async_constant(x) } } do() } x <- synchronise(when_any(loop())) expect_equal(length(x), 5L) expect_equal(nrow(x[[2]]), nrow(x[[5]])) })