tests/testthat/test-deferred.R

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]]))
})
gaborcsardi/async documentation built on Nov. 20, 2024, 4:51 p.m.