Skip to content

Commit 1594179

Browse files
committed
Merge branch 'main' into pkg_support
* main: chore: Migrate `{httr}` to `{httr2}` (#420)
2 parents ba1ce03 + 1fcf7c9 commit 1594179

File tree

9 files changed

+81
-37
lines changed

9 files changed

+81
-37
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Imports:
2929
cli,
3030
fs,
3131
globals (>= 0.14.0),
32-
httr,
32+
httr2,
3333
jsonlite,
3434
lifecycle (>= 1.0.3),
3535
pingr,
@@ -97,7 +97,7 @@ Collate:
9797
'cpp11.R'
9898
'expect-snapshot.R'
9999
'expr-recurse.R'
100-
'httr.R'
100+
'httr2.R'
101101
'migrate.R'
102102
'missing-value.R'
103103
'utils.R'

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
* Fixed internal bug where `{testthat}` v3.3.0 changed expectation behavior for screenshot snapshots within `App$expect_values()` (#418).
88

9+
* Migrated from `{httr}` to `{httr2}` for all HTTP requests made by `{shinytest2}` (#420).
10+
911
# shinytest2 0.4.1
1012

1113
## Bug

R/R6-helper.R

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
2-
Count <- R6Class( # nolint
1+
# nolint start
2+
Count <- R6Class(
3+
# nolint end
34
"Count",
45
private = list(
56
count = 0
@@ -16,7 +17,8 @@ Count <- R6Class( # nolint
1617
)
1718

1819
app_next_temp_snapshot_path <- function(
19-
self, private,
20+
self,
21+
private,
2022
name, # full path or filename
2123
ext = "json"
2224
) {
@@ -36,7 +38,9 @@ app_next_temp_snapshot_path <- function(
3638
}
3739

3840

39-
Url <- R6Class( # nolint
41+
# nolint start
42+
Url <- R6Class(
43+
# nolint end
4044
"Url",
4145
private = list(
4246
url = NULL
@@ -46,9 +50,27 @@ Url <- R6Class( # nolint
4650
private$url
4751
},
4852
set = function(url) {
49-
res <- httr::parse_url(url)
53+
res <- tryCatch(
54+
httr2::url_parse(url),
55+
error = function(e) {
56+
# httr2::url_parse() uses curl underneath which is stricter
57+
# Convert parsing errors to validation errors
58+
if (grepl("Port number", e$message)) {
59+
warning(e$message)
60+
stop("Assertion on 'url port' failed")
61+
}
62+
if (grepl("parse URL", e$message)) {
63+
stop("Assertion on 'url hostname' failed: Must be a single string")
64+
}
65+
stop(e)
66+
}
67+
)
5068

51-
checkmate::assert_subset(res$scheme, c("http", "https"), .var.name = "url scheme")
69+
checkmate::assert_subset(
70+
res$scheme,
71+
c("http", "https"),
72+
.var.name = "url scheme"
73+
)
5274

5375
if (!is.null(res$port)) {
5476
res$port <- as.integer(res$port)
@@ -57,7 +79,7 @@ Url <- R6Class( # nolint
5779

5880
ckm8_assert_single_string(res$hostname, .var.name = "url hostname")
5981

60-
private$url <- httr::build_url(res)
82+
private$url <- httr2::url_build(res)
6183

6284
invisible(self)
6385
}

R/app-driver-expect-download.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ app_download <- function(
2020

2121
# Add the base location to the URL
2222
full_url <- paste0(private$shiny_url$get(), sub_url)
23-
req <- app_httr_get(self, private, full_url)
23+
req <- app_httr2_get(self, private, full_url)
2424

2525
# Find suggested name
26-
content_dispo <- httr::headers(req)[["content-disposition"]]
26+
content_dispo <- httr2::resp_headers(req)[["content-disposition"]]
2727
filename_header <- NULL
2828
if (
2929
length(content_dispo) == 1 &&
@@ -75,7 +75,7 @@ app_download <- function(
7575
fs::path_sanitize(filename, "_")
7676
)
7777
# Save contents
78-
writeBin(req$content, download_path)
78+
writeBin(httr2::resp_body_raw(req), download_path)
7979

8080
list(
8181
download_path = download_path,

R/app-driver-expect-values.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ app_get_values <- function(
124124

125125
# Ask Shiny for info
126126
cur_env <- rlang::current_env()
127-
req <- app_httr_get(self, private, url, fn_404 = function(req) {
127+
req <- app_httr2_get(self, private, url, fn_404 = function(req) {
128128
app_abort(
129129
self,
130130
private,
@@ -168,7 +168,7 @@ app_get_values <- function(
168168

169169
tmpfile <- tempfile()
170170
on.exit(unlink(tmpfile), add = TRUE)
171-
writeBin(req$content, tmpfile)
171+
writeBin(httr2::resp_body_raw(req), tmpfile)
172172
values <- readRDS(tmpfile)
173173

174174
if (hash_images) {
@@ -226,7 +226,7 @@ app_expect_values <- function(
226226
)
227227
# Ask Shiny for info
228228
cur_env <- rlang::current_env()
229-
req <- app_httr_get(self, private, url, fn_404 = function(req) {
229+
req <- app_httr2_get(self, private, url, fn_404 = function(req) {
230230
app_abort(
231231
self,
232232
private,
@@ -239,7 +239,7 @@ app_expect_values <- function(
239239
})
240240

241241
# Convert to text, then replace base64-encoded images with hashes.
242-
content <- raw_to_utf8(req$content)
242+
content <- raw_to_utf8(httr2::resp_body_raw(req))
243243
# original_content <- content
244244
content <- hash_snapshot_image_data(content, is_json_file = TRUE)
245245
# Adjust the text to _pretty_ print
Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,60 @@
1-
app_httr_get <- function(self, private, url, fn_404 = NULL) {
1+
app_httr2_get <- function(self, private, url, fn_404 = NULL) {
22
ckm8_assert_app_driver(self, private)
33

4-
pieces <- httr::parse_url(url)
4+
pieces <- httr2::url_parse(url)
55
# Add in port information if it's missing
66
# https://github.com/rstudio/shinytest2/issues/158
77
if (is.null(pieces$port)) {
88
pieces$port <- switch(pieces$scheme, "http" = 80, "https" = 443)
99
}
1010

1111
if (!pingr::is_up(pieces$hostname, pieces$port, check_online = FALSE)) {
12-
app_abort(self, private, "Could not find Shiny server. Shiny app is no longer running")
12+
app_abort(
13+
self,
14+
private,
15+
"Could not find Shiny server. Shiny app is no longer running"
16+
)
1317
}
1418

15-
withCallingHandlers( # abort() on error
16-
{ # nolint
17-
req <- httr::GET(url)
19+
withCallingHandlers(
20+
# abort() on error
21+
{
22+
# nolint
23+
req <- httr2::request(url)
24+
req <- httr2::req_error(req, is_error = function(resp) FALSE)
25+
req <- httr2::req_perform(req)
1826
},
1927
# Attempt to capture empty reply error and provide better message
2028
error = function(e) {
2129
if (grepl("Empty reply from server", as.character(e), fixed = TRUE)) {
22-
app_abort(self, private, "Empty reply received from Shiny server. Shiny app is no longer running", parent = e)
30+
app_abort(
31+
self,
32+
private,
33+
"Empty reply received from Shiny server. Shiny app is no longer running",
34+
parent = e
35+
)
2336
}
2437
# Unknown error, rethrow
2538
app_abort(self, private, e)
2639
}
2740
)
2841

29-
status <- httr::status_code(req)
42+
status <- httr2::resp_status(req)
3043
if (status == 200) {
3144
return(req)
3245
}
3346
if (status == 404 && is.function(fn_404)) {
3447
return(fn_404(req))
3548
}
3649

37-
cat("{shinytest2} query failed (", status, ")----------------------\n", sep = "")
50+
cat(
51+
"{shinytest2} query failed (",
52+
status,
53+
")----------------------\n",
54+
sep = ""
55+
)
3856
cat("URL: ", url, "\n", sep = "")
39-
cat(httr::content(req, "text"), "\n")
57+
cat(httr2::resp_body_string(req), "\n")
4058
cat("----------------------------------------\n")
4159
app_abort(self, private, "Unable request data from server")
4260
}

tests/testthat/apps/task-button/app.R

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ input_task_button <- yoink("bslib", "input_task_button")
88
bind_task_button <- yoink("bslib", "bind_task_button")
99

1010

11-
1211
ui <- fluidPage(
1312
actionButton("run_normal", "Run normal"),
1413
textOutput("normal_result"),
@@ -26,13 +25,16 @@ server <- function(input, output, session) {
2625
task <- ExtendedTask$new(function() {
2726
promise(function(resolve, reject) {
2827
# Use later to simulate future promise calls
29-
later(function() {
30-
resolve(slow_function())
31-
# Add extra time for extra checks
32-
}, delay = 0.01)
28+
later(
29+
function() {
30+
resolve(slow_function())
31+
# Add extra time for extra checks
32+
},
33+
delay = 0.01
34+
)
3335
})
34-
}) |> bind_task_button("run_async")
35-
36+
}) |>
37+
bind_task_button("run_async")
3638

3739
# Normal
3840
observeEvent(input$run_normal, {

tests/testthat/test-save-app.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ require("shiny", quietly = TRUE, character.only = TRUE)
44
test_that("Make sure global vars are set - issue303", {
55
# Only run on CI. CRAN requires package to be installed to run `callr::rscript()
66
skip_if(!on_ci(), "Only run on CI")
7+
skip_on_os("windows")
78

89
# Run the script in a global environment that does not polute this global environment
910
p <- callr::rscript("scripts/issue_303.R", show = FALSE)
@@ -21,6 +22,7 @@ test_that("Make sure global vars are set - issue303", {
2122
test_that("Make sure global vars are set - pr307", {
2223
# Only run on CI. CRAN requires package to be installed to run `callr::rscript()
2324
skip_if(!on_ci(), "Only run on CI")
25+
skip_on_os("windows")
2426

2527
# Run the script in a global environment that does not polute this global environment
2628
p <- callr::rscript("scripts/pr_307.R", show = FALSE)
@@ -83,7 +85,6 @@ test_that("can run saved app", {
8385
})
8486

8587

86-
8788
test_that("can get ui and server from app", {
8889
ui <- fluidPage("Hi!")
8990
server <- function(input, output, session) {

tests/testthat/test-url.R

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
21
test_that("Url Class behaves as expected", {
3-
42
expect_url <- function(url, expected_url) {
53
expect_equal(Url$new()$set(url)$get(), expected_url)
64
}
@@ -15,11 +13,12 @@ test_that("Url Class behaves as expected", {
1513
expect_url("http://user@a.b.com/", "http://user@a.b.com/")
1614
expect_url("http://user:pass@a.b.com/", "http://user:pass@a.b.com/")
1715

16+
expect_url("http:/a.b.com/", "http://a.b.com/")
17+
1818
# Malformed URLs, or non-http/https protocol
1919
expect_url_error <- function(url, ...) {
2020
expect_error(Url$new()$set(url), ...)
2121
}
22-
expect_url_error("http:/a.b.com/", "url hostname")
2322
expect_warning(
2423
expect_url_error("http://a.b.com:12ab/", "url port")
2524
)

0 commit comments

Comments
 (0)