Skip to content

Commit b9aa792

Browse files
committed
Merge commit '608decce7eb4bd198c0ff28dae0eb9b0c72e040d'
2 parents 60d0eb7 + 608decc commit b9aa792

File tree

248 files changed

+8935
-1764
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

248 files changed

+8935
-1764
lines changed

.claude/settings.local.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
{
2+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
23
"permissions": {
34
"allow": [
4-
"Bash(find:*)"
5+
"Bash(find:*)",
6+
"Bash(R:*)",
7+
"Bash(rm:*)",
8+
"Bash(air format:*)",
9+
"Edit(R/**)",
10+
"Edit(tests/**)",
11+
"Edit(vignettes/**)"
512
],
613
"deny": []
714
}
8-
}
15+
}

CLAUDE.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,23 @@ testthat is R's most popular unit testing framework, used by thousands of CRAN p
88

99
## Key Development Commands
1010

11-
### Testing
12-
- `devtools::test()` or `Ctrl/Cmd+Shift+T` in RStudio - Run all tests
13-
- `devtools::test_file("tests/testthat/test-filename.R")` - Run tests in a specific file
14-
- `testthat::test_local()` - Run tests for local source package
15-
- `testthat::test_package("testthat")` - Run tests for installed package
16-
- `R CMD check` - Full package check including tests
11+
General advice:
12+
* When running R from the console, always run it with `--quiet --vanilla`
13+
* Always run `air format .` after generating code
14+
15+
### Development tools
1716

18-
### Building and Installation
19-
- `devtools::load_all()` or `Ctrl/Cmd+Shift+L` - Load package for development
20-
- `devtools::document()` - Generate documentation
17+
- `devtools::test()` - Run all tests
18+
- `devtools::test_file("tests/testthat/test-filename.R")` - Run tests in a specific file
19+
- DO NOT USE `devtools::test_active_file()`
20+
- `devtools::load_all()` - Load package for development
2121
- `devtools::check()` - Run R CMD check
2222
- `devtools::install()` - Install package locally
2323

24+
### Documentation
25+
26+
- Always run `devtools::document()` after changing any roxygen2 docs.
27+
2428
## Core Architecture
2529

2630
### Main Components

DESCRIPTION

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ BugReports: https://github.com/r-lib/testthat/issues
1717
Depends:
1818
R (>= 4.1.0)
1919
Imports:
20-
brio (>= 1.1.3),
21-
callr (>= 3.7.3),
22-
cli (>= 3.6.1),
23-
desc (>= 1.4.2),
24-
evaluate (>= 1.0.1),
25-
jsonlite (>= 1.8.7),
26-
lifecycle (>= 1.0.3),
20+
brio (>= 1.1.5),
21+
callr (>= 3.7.6),
22+
cli (>= 3.6.5),
23+
desc (>= 1.4.3),
24+
evaluate (>= 1.0.4),
25+
jsonlite (>= 2.0.0),
26+
lifecycle (>= 1.0.4),
2727
magrittr (>= 2.0.3),
2828
methods,
29-
pkgload (>= 1.3.2.1),
29+
pkgload (>= 1.4.0),
3030
praise (>= 1.0.0),
31-
processx (>= 3.8.2),
32-
ps (>= 1.7.5),
33-
R6 (>= 2.5.1),
34-
rlang (>= 1.1.1),
31+
processx (>= 3.8.6),
32+
ps (>= 1.9.1),
33+
R6 (>= 2.6.1),
34+
rlang (>= 1.1.6),
3535
utils,
36-
waldo (>= 0.6.0),
36+
waldo (>= 0.6.2),
3737
withr (>= 3.0.2)
3838
Suggests:
3939
covr,

NAMESPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export(ProgressReporter)
4545
export(RStudioReporter)
4646
export(Reporter)
4747
export(SilentReporter)
48+
export(SlowReporter)
4849
export(StopReporter)
4950
export(SummaryReporter)
5051
export(TapReporter)
@@ -114,6 +115,7 @@ export(expect_no_warning)
114115
export(expect_null)
115116
export(expect_output)
116117
export(expect_output_file)
118+
export(expect_r6_class)
117119
export(expect_reference)
118120
export(expect_s3_class)
119121
export(expect_s4_class)
@@ -190,6 +192,7 @@ export(skip_on_os)
190192
export(skip_on_travis)
191193
export(skip_unless_r)
192194
export(snapshot_accept)
195+
export(snapshot_reject)
193196
export(snapshot_review)
194197
export(source_dir)
195198
export(source_file)
@@ -228,5 +231,6 @@ import(rlang)
228231
importFrom(R6,R6Class)
229232
importFrom(brio,readLines)
230233
importFrom(brio,writeLines)
234+
importFrom(lifecycle,deprecated)
231235
importFrom(magrittr,"%>%")
232236
useDynLib(testthat, .registration = TRUE)

NEWS.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
11
# testthat (development version)
22

3-
* `expect_matches()` failures should be a little easier to read (#2135).
3+
* `test_dir()`, `test_file()`, `test_package()`, `test_check()`, `test_local()`, `source_file()` gain a `shuffle` argument uses `sample()` to randomly reorder the top-level expressions in each test file (#1942). This random reordering surfaces dependencies between tests and code outside of any test, as well as dependencies between tests. This helps you find and eliminate unintentional dependencies.
4+
* `snapshot_accept(test)` now works when the test file name contains `.` (#1669).
5+
* `local_mock()` and `with_mock()` have been deprecated because they are no longer permitted in R 4.5.
6+
* `snapshot_review()` now passes `...` on to `shiny::runApp()` (#1928).
7+
* `expect_named()` now gives more informative errors (#2091).
8+
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
9+
* `test_that()` no longer warns about the absence of `{}` since it no longer seems to be necessary.
10+
* `test_that()`, `describe()`, and `it()` can now be arbitrarily nested. Each component will skip only if it and its subtests don't contain any expectations. The interactive stop reporter has been fixed so it doesn't duplicate failures. (#2063, #2188).
11+
* Test filtering now works with `it()`, and the `desc` argument can take a character vector in order to recursively filter subtests (i.e. `it()` nested inside of `describe()`) (#2118).
12+
* New `snapshot_reject()` rejects all modified snapshots by deleting the `.new` variants (#1923).
13+
* New `SlowReporter` makes it easier to find the slowest tests in your package. The easiest way to run it is with `devtools::test(reporter = "slow")` (#1466).
14+
* Power `expect_mapequal()` with `waldo::compare(list_as_map = TRUE)` (#1521).
15+
* On CRAN, `test_that()` now automatically skips if a package is not installed (#1585). Practically, this means that you no longer need to check that suggested packages are installed. (We don't do this in the tidyverse because we think it has limited payoff, but other styles advise differently.)
16+
* `expect_snapshot()` no longer skips on CRAN, as that skips the rest of the test. Instead it just returns, neither succeeding nor failing (#1585).
17+
* Interrupting a test now prints the test name. This makes it easier to tell where a very slow test might be hanging (#1464)
18+
* Parallel testthat now does not ignore test files with syntax errors (#1360).
19+
* `expect_lt()`, `expect_gt()`, and friends have a refined display that is more likely to display the correct number of digits and shows you the actual values compared.
20+
* `describe()`, `it()`, and `test_that()` now have a shared stack of descriptions so that if you nest any inside of each other, any resulting failures will show you the full path.
21+
* `describe()` now correctly scopes `skip()` (#2007).
22+
* `ParallelProgressReporter` now respect `max_failures` (#1162).
23+
* The last snapshot is no longer lost if the snapshot file is missing the final newline (#2092). It's easy to accidentally remove this because there are two trailing new lines in snapshot files and many editors will automatically remove if you touch the file.
24+
* New `expect_r6_class()` (#2030).
25+
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
26+
* `JunitReporter()` no longer fails with `"no applicable method for xml_add_child"` for warnings outside of tests (#1913). Additionally, warnings now save their backtraces.
27+
* `JunitReporter()` strips ANSI escapes in more placese (#1852, #2032).
28+
* `try_again()` is now publicised. The first argument is now the number of retries, not tries (#2050).
29+
* `vignette("custom-expectations)` has been overhauled to make it much clearer how to create high-quality expectations (#2113, #2132, #2072).
30+
* `expect_snapshot()` and friends will now fail when creating a new snapshot on CI. This is usually a signal that you've forgotten to run it locally before committing (#1461).
31+
* `expect_snapshot_value()` can now handle expressions that generate `-` (#1678) or zero length atomic vectors (#2042).
32+
* `expect_matches()` failures should be a little easier to read (#2135, #2181).
433
* New `local_on_cran(TRUE)` allows you to simulate how your tests will run on CRAN (#2112).
534
* `expect_no_*()` now executes the entire code block, rather than stopping at the first message or warning (#1991).
635
* `expect_no_failures()` and `expect_no_successes()` are now deprecated as `expect_success()` now test for no failures and `expect_failure()` tests for no successes (#)
@@ -14,7 +43,7 @@
1443
* Fixed an issue preventing compilation from succeeding due to deprecation / removal of `std::uncaught_exception()` (@kevinushey, #2047).
1544
* New `skip_unless_r()` to skip running tests on unsuitable versions of R, e.g. `skip_unless_r(">= 4.1.0")` to skip tests that require, say, `...names` (@MichaelChirico, #2022)
1645
* `skip_on_os()` gains an option `"emscripten"` of the `os` argument to skip tests on Emscripten (@eitsupi, #2103).
17-
* New expectation, `expect_shape()`, for testing the shape (i.e., the `length()`, `nrow()`, `ncol()`, or `dim()`), all in one place (#1423, @michaelchirico).
46+
* New expectation, `expect_shape()`, for testing the shape (i.e., the `nrow()`, `ncol()`, or `dim()`), all in one place (#1423, @michaelchirico).
1847

1948
# testthat 3.2.3
2049

R/auto-test.R

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
#' Watches code and tests for changes, rerunning tests as appropriate.
22
#'
3+
#' @description
4+
#' `r lifecycle::badge("superseded")`
5+
#'
36
#' The idea behind `auto_test()` is that you just leave it running while
47
#' you develop your code. Every time you save a file it will be automatically
58
#' tested and you can easily see if your changes have caused any test
6-
#' failures.
9+
#' failures.
710
#'
811
#' The current strategy for rerunning tests is as follows:
912
#'
1013
#' - if any code has changed, then those files are reloaded and all tests
1114
#' rerun
1215
#' - otherwise, each new or modified test is run
13-
#'
14-
#' In the future, `auto_test()` might implement one of the following more
15-
#' intelligent alternatives:
16-
#'
17-
#' - Use codetools to build up dependency tree and then rerun tests only
18-
#' when a dependency changes.
19-
#' - Mimic ruby's autotest and rerun only failing tests until they pass,
20-
#' and then rerun all tests.
21-
#
2216
#' @seealso [auto_test_package()]
2317
#' @export
2418
#' @param code_path path to directory containing code
@@ -27,7 +21,7 @@
2721
#' @param env environment in which to execute test suite.
2822
#' @param hash Passed on to [watch()]. When FALSE, uses less accurate
2923
#' modification time stamps, but those are faster for large files.
30-
#' @keywords debugging
24+
#' @keywords internal
3125
auto_test <- function(
3226
code_path,
3327
test_path,
@@ -67,15 +61,12 @@ auto_test <- function(
6761
watch(c(code_path, test_path), watcher, hash = hash)
6862
}
6963

70-
#' Watches a package for changes, rerunning tests as appropriate.
71-
#'
7264
#' @param pkg path to package
7365
#' @export
7466
#' @param reporter test reporter to use
7567
#' @param hash Passed on to [watch()]. When FALSE, uses less accurate
7668
#' modification time stamps, but those are faster for large files.
77-
#' @keywords debugging
78-
#' @seealso [auto_test()] for details on how method works
69+
#' @rdname auto_test
7970
auto_test_package <- function(
8071
pkg = ".",
8172
reporter = default_reporter(),

R/compare.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ compare <- function(x, y, ...) {
1616
}
1717

1818
comparison <- function(equal = TRUE, message = "Equal") {
19-
stopifnot(is.logical(equal), length(equal) == 1)
20-
stopifnot(is.character(message))
19+
check_bool(equal)
20+
check_character(message)
2121

2222
structure(
2323
list(

R/deprec-condition.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ capture_warnings <- function(code, ignore_deprecation = FALSE) {
129129
}
130130

131131
get_messages <- function(x) {
132-
vapply(x, cnd_message, FUN.VALUE = character(1))
132+
map_chr(x, cnd_message)
133133
}
134134

135135
#' Is an error informative?

R/describe.R

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#'
2727
#' @param description description of the feature
2828
#' @param code test code containing the specs
29+
#' @keywords internal
2930
#' @export
3031
#' @examples
3132
#' describe("matrix()", {
@@ -56,43 +57,18 @@
5657
#' it("can handle division by 0") #not yet implemented
5758
#' })
5859
#' })
59-
6060
describe <- function(description, code) {
61-
check_string(description, allow_empty = FALSE)
62-
describe_description <- description
63-
64-
# prepares a new environment for each it-block
65-
describe_environment <- new.env(parent = parent.frame())
66-
describe_environment$it <- function(description, code = NULL) {
67-
check_string(description, allow_empty = FALSE)
68-
code <- substitute(code)
61+
local_description_push(description)
6962

70-
description <- paste0(describe_description, ": ", description)
71-
describe_it(description, code, describe_environment)
72-
}
73-
74-
eval(substitute(code), describe_environment)
75-
invisible()
76-
}
77-
78-
describe_it <- function(description, code, env = parent.frame()) {
79-
reporter <- get_reporter() %||% local_interactive_reporter()
80-
local_test_context()
81-
82-
test_code(
83-
description,
84-
code,
85-
env = env,
86-
reporter = reporter,
87-
skip_on_empty = FALSE
88-
)
63+
code <- substitute(code)
64+
test_code(code, parent.frame())
8965
}
9066

9167
#' @export
9268
#' @rdname describe
9369
it <- function(description, code = NULL) {
94-
check_string(description, allow_empty = FALSE)
70+
local_description_push(description)
9571

9672
code <- substitute(code)
97-
describe_it(description, code, env = parent.frame())
73+
test_code(code, parent.frame())
9874
}

R/edition.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ edition_deprecate <- function(in_edition, what, instead = NULL) {
2727
return()
2828
}
2929

30-
warn(c(
31-
paste0("`", what, "` was deprecated in ", edition_name(in_edition), "."),
30+
cli::cli_warn(c(
31+
"{.code {what}} was deprecated in {edition_name(in_edition)}.",
3232
i = instead
3333
))
3434
}
@@ -40,7 +40,7 @@ edition_require <- function(in_edition, what) {
4040
return()
4141
}
4242

43-
stop(paste0("`", what, "` requires ", edition_name(in_edition), "."))
43+
cli::cli_abort("{.code {what}} requires {edition_name(in_edition)}.")
4444
}
4545

4646
edition_name <- function(x) {

0 commit comments

Comments
 (0)