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 131 132 133 134 135 136
|
test_that("checks its inputs", {
req <- request_test("/status/:status", status = 200)
expect_snapshot(error = TRUE, {
req_perform_promise(1)
req_perform_promise(req, path = 1)
req_perform_promise(req, pool = "INVALID")
req_perform_promise(req, verbosity = "INVALID")
})
})
test_that("returns a promise that resolves", {
p1 <- req_perform_promise(request_test("/delay/:secs", secs = 0.25))
p2 <- req_perform_promise(request_test("/delay/:secs", secs = 0.25))
expect_s3_class(p1, "promise")
expect_s3_class(p2, "promise")
p1_value <- extract_promise(p1)
expect_equal(resp_status(p1_value), 200)
p2_value <- extract_promise(p2)
expect_equal(resp_status(p2_value), 200)
})
test_that("correctly prepares request", {
req <- request_test("/post") %>% req_method("POST")
prom <- req_perform_promise(req)
expect_no_error(extract_promise(prom))
})
test_that("correctly prepares request", {
req <- request_test("/get")
expect_snapshot(
. <- extract_promise(req_perform_promise(req, verbosity = 1)),
transform = function(x) {
gsub("(Date|Host|User-Agent|ETag|Content-Length|Accept-Encoding): .*", "\\1: <variable>", x)
}
)
})
test_that("can promise to download files", {
req <- request_test("/json")
path <- withr::local_tempfile()
p <- req_perform_promise(req, path)
expect_s3_class(p, "promise")
p_value <- extract_promise(p)
expect_equal(p_value$body, new_path(path))
# And check that something was downloaded
expect_gt(file.size(path), 0)
})
test_that("promises can retrieve from cache", {
req <- request("http://example.com") %>% req_cache(tempfile())
resp <- response(200,
headers = "Expires: Wed, 01 Jan 3000 00:00:00 GMT",
body = charToRaw("abc")
)
cache_set(req, resp)
p <- req_perform_promise(req)
expect_s3_class(p, "promise")
p_value <- extract_promise(p)
expect_equal(p_value, resp)
})
test_that("both curl and HTTP errors in promises are rejected", {
expect_error(
extract_promise(
req_perform_promise(request_test("/status/:status", status = 404))
),
class = "httr2_http_404"
)
expect_error(
extract_promise(
req_perform_promise(request("INVALID"))
),
class = "httr2_failure"
)
})
test_that("req_perform_promise doesn't leave behind poller", {
skip_if_not(later::loop_empty(), "later::global_loop not empty when test started")
p <- req_perform_promise(request_test("/delay/:secs", secs = 0.25))
# Before promise is resolved, there should be an operation in our later loop
expect_false(later::loop_empty())
p_value <- extract_promise(p)
# But now that that our promise is resolved, we shouldn't still be polling the pool
expect_true(later::loop_empty())
})
test_that("req_perform_promise can use non-default pool", {
custom_pool <- curl::new_pool()
p1 <- req_perform_promise(request_test("/delay/:secs", secs = 0.25))
p2 <- req_perform_promise(request_test("/delay/:secs", secs = 0.25), pool = custom_pool)
expect_equal(length(curl::multi_list(custom_pool)), 1)
p1_value <- extract_promise(p1)
expect_equal(resp_status(p1_value), 200)
p2_value <- extract_promise(p2)
expect_equal(resp_status(p2_value), 200)
})
test_that("req_perform_promise uses the default loop", {
# The main reason for temp loops is to allow an asynchronous operation to be
# created, waited on, and resolved/rejected inside of a synchronous function,
# all without affecting any asynchronous operations that existed before the
# temp loop was created.
# This can't proceed within the temp loop
p1 <- req_perform_promise(request_test("/delay/:secs", secs = 0.25))
later::with_temp_loop({
# You can create an async response with explicit pool=NULL, but it can't
# proceed until the temp loop is over
p2 <- req_perform_promise(request_test("/get"), pool = NULL)
# You can create an async response with explicit pool=pool, and it can
# proceed as long as that pool was first used inside of the temp loop
p3 <- req_perform_promise(request_test("/get"), pool = curl::new_pool())
# You can't create an async response in the temp loop without explicitly
# specifying a pool
expect_snapshot(p4 <- req_perform_promise(request_test("/get")), error = TRUE)
# Like I said, you can create this, but it won't work until we get back
# outside the temp loop
expect_null(extract_promise(p2, timeout = 1))
# This works fine inside the temp loop, because its pool was first used
# inside
expect_equal(resp_status(extract_promise(p3, timeout = 1)), 200)
})
# These work fine now that we're back outside the temp loop
expect_equal(resp_status(extract_promise(p1, timeout = 1)), 200)
expect_equal(resp_status(extract_promise(p2, timeout = 1)), 200)
})
|