Skip to content

Commit 8a75d2d

Browse files
committed
✨ More proofreading ✨
1 parent d27dd24 commit 8a75d2d

File tree

6 files changed

+17
-17
lines changed

6 files changed

+17
-17
lines changed

vignettes/challenging-tests.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ continue <- function(prompt) {
9292
readline <- NULL
9393
```
9494

95-
You can test its behaviour by mocking `readline()` and using a snapshot test:
95+
You can test its behavior by mocking `readline()` and using a snapshot test:
9696

9797
```{r}
9898
#| label: mock-readline

vignettes/custom-expectation.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ expect_length <- function(object, n) {
4343
}
4444
```
4545

46-
The first step in any expectation is to use `quasi_label()` to capture a "labelled value", i.e., a list that contains both the value (`$val`) for testing and a label (`$lab`) for messaging. This is a pattern that exists for fairly esoteric reasons; you don't need to understand it, just copy and paste it 🙂.
46+
The first step in any expectation is to use `quasi_label()` to capture a "labeled value", i.e., a list that contains both the value (`$val`) for testing and a label (`$lab`) for messaging. This is a pattern that exists for fairly esoteric reasons; you don't need to understand it, just copy and paste it 🙂.
4747

4848
Next you need to check each way that `object` could violate the expectation. In this case, there's only one check, but in more complicated cases there can be multiple checks. In most cases, it's easier to check for violations one by one, using early returns to `fail()`. This makes it easier to write informative failure messages that first describe what was expected and then what was actually seen.
4949

@@ -217,5 +217,5 @@ expect_length <- function(object, n) {
217217
A few recommendations:
218218

219219
* The helper shouldn't be user facing, so we give it a `_` suffix to make that clear.
220-
* It's typically easiest for a helper to take the labelled value produced by `quasi_label()`.
220+
* It's typically easiest for a helper to take the labeled value produced by `quasi_label()`.
221221
* Your helper should usually call both `fail()` and `pass()` and be returned from the wrapping expectation.

vignettes/mocking.Rmd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,9 @@ test_that("elapsed() measures elapsed time", {
201201

202202
## How does mocking work?
203203

204-
To finish up, it's worth discussing how mocking works. It took us some iteration (`testthat::with_mock()`, as well as {mockery}, {mockr}, and {mockthat} packages) to get to current state and understanding how it works will help you to understand some of the tradeoffs.
204+
To finish up, it's worth discussing how mocking works. It took us some iteration (`testthat::with_mock()`, as well as {mockery}, {mockr}, and {mockthat} packages) to get to the current state, and understanding how it works will help you understand some of the tradeoffs.
205205

206-
The fundamental tension of mocking is that you want it to actually work (i.e. temporarily modify the implementation of a function), but also be "hygienic", i.e. it should only allow you to modify functions that you own, not arbitrarily affect any code. To achieve this goal `local_mocked_bindings()` works by modifying an environment that you own: your package's namespace environment. (If you've forgotten exactly what these are, you can refresh your memory at <https://adv-r.hadley.nz/environments.html#special-environments>.) So you can imagine mocking works something like this if you're temporarily replacing the value of `my_function` with a `new` implementation:
206+
The fundamental tension of mocking is that you want it to actually work (i.e., temporarily modify the implementation of a function), but also be "hygienic", i.e., it should only allow you to modify functions that you own, not arbitrarily affect any code. To achieve this goal, `local_mocked_bindings()` works by modifying an environment that you own: your package's namespace environment. (If you've forgotten exactly what these are, you can refresh your memory at <https://adv-r.hadley.nz/environments.html#special-environments>.) So you can imagine mocking works something like this if you're temporarily replacing the value of `my_function` with a `new` implementation:
207207

208208
```{r}
209209
#| eval: false
@@ -219,8 +219,8 @@ assignInNamespace("my_function", old, "mypackage")
219219

220220
This leads to the two limitations of `local_mocked_bindings()`:
221221

222-
1. The package namespace is locked, which means that you can't add new bindings to it. That means if you want to mock base functions, you have to provide some binding that can be overridden. The easiest way to do this is (e.g.) `mean <- NULL`. This creates a binding that `local_mocked_bindings()` can modify, but because of R's [lexical scoping rules](https://adv-r.hadley.nz/functions.html#functions-versus-variables) this doesn't affect ordinary calls to `mean()`.
222+
1. The package namespace is locked, which means that you can't add new bindings to it. That means if you want to mock base functions, you have to provide some binding that can be overridden. The easiest way to do this is (e.g., `mean <- NULL`). This creates a binding that `local_mocked_bindings()` can modify, but because of R's [lexical scoping rules](https://adv-r.hadley.nz/functions.html#functions-versus-variables) this doesn't affect ordinary calls to `mean()`.
223223

224-
1. `::` doesn't use the package namespace, so if you want to mock a function from another package that you call with `::`, you either have to switch from `pkg::fun()` to `fun()` by importing `fun` into your `NAMESPACE` (e.g. with `@importFrom pkg fun`), or create your own wrapper function that you can mock. Typically, one of these options will feel fairly natural.
224+
1. `::` doesn't use the package namespace, so if you want to mock a function from another package that you call with `::`, you either have to switch from `pkg::fun()` to `fun()` by importing `fun` into your `NAMESPACE` (e.g., with `@importFrom pkg fun`), or create your own wrapper function that you can mock. Typically, one of these options will feel fairly natural.
225225

226226
Overall these limitations feel correct to me: `local_mocked_bindings()` makes it easy to temporarily change the implementation of functions that you have written, while offering workarounds to override the implementations of functions that others have written in the scope of your package.

vignettes/skipping.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ You should keep an eye on this when developing interactively to make sure that y
6161

6262
## Helpers
6363

64-
If you find yourself using the same `skip_if()`/`skip_if_not()` expression across multiple tests, it's a good idea to create a helper function.
64+
If you find yourself using the same `skip_if()` or `skip_if_not()` expression across multiple tests, it's a good idea to create a helper function.
6565
This function should start with `skip_` and live in a `tests/testthat/helper-{something}.R` file:
6666

6767
```{r}
@@ -98,7 +98,7 @@ convert_markdown_to_html <- function(in_path, out_path, ...) {
9898
```
9999

100100
If Pandoc is not available when `convert_markdown_to_html()` executes, it throws an error *unless* it appears to be part of a test run, in which case the test is skipped.
101-
This is an alternative to implementing a custom skipper, e.g. `skip_if_no_pandoc()`, and inserting it into many of pkgdown's tests.
101+
This is an alternative to implementing a custom skipper, e.g., `skip_if_no_pandoc()`, and inserting it into many of pkgdown's tests.
102102

103103
We don't want pkgdown to have a runtime dependency on testthat, so pkgdown includes a copy of `testthat::is_testing()`:
104104

vignettes/snapshotting.Rmd

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ test_that("actionable feedback if some or all arguments named", {
237237

238238
Sometimes part of the output varies in ways that you can't easily control. In many cases, it's convenient to use mocking (`vignette("mocking")`) to ensure that every run of the function always produces the same output. In other cases, it's easier to manipulate the text output with a regular expression or similar. That's the job of the `transform` argument which should be passed a function that takes a character vector of lines, and returns a modified vector.
239239

240-
This type of problem often crops up when you are testing a function that gives feedback about a path. In your tests, you'll typically use a temporary path (e.g. from `withr::local_tempfile()`) so if you display the path in a snapshot, it will be different every time.
240+
This type of problem often crops up when you are testing a function that gives feedback about a path. In your tests, you'll typically use a temporary path (e.g., from `withr::local_tempfile()`) so if you display the path in a snapshot, it will be different every time.
241241
For example, consider this "safe" version of `writeLines()` that requires you to explicitly opt-in to overwriting an existing file:
242242

243243
```{r}
@@ -308,20 +308,20 @@ Now even though the path varies, the snapshot does not.
308308
By default, testthat sets a number of options that simplify and standardise output:
309309

310310
* The console width is set to 80.
311-
* Crayon/cli ANSI colouring and hyperlinks are suppressed.
311+
* Crayon/cli ANSI coloring and hyperlinks are suppressed.
312312
* Unicode characters are suppressed.
313313

314-
These are sound defaults that we have found useful to minimise spurious difference between tests run in different environments. However, there are times when you want to deliberately test different widths, or ANSI escapes, or unicode characters, so you can override the defaults with `local_reproducible_output()`.
314+
These are sound defaults that we have found useful to minimize spurious differences between tests run in different environments. However, there are times when you want to deliberately test different widths, or ANSI escapes, or Unicode characters, so you can override the defaults with `local_reproducible_output()`.
315315

316316
### Snapshotting graphics
317317

318-
If you need to test graphical output, use {vdiffr}. vdiffr is used to test ggplot2, and incorporates everything we know about high-quality graphics tests that minimise false positives. Graphics testing is still often fragile, but using vdiffr means you will avoid all the problems we know how to avoid.
318+
If you need to test graphical output, use {vdiffr}. vdiffr is used to test ggplot2, and incorporates everything we know about high-quality graphics tests that minimize false positives. Graphics testing is still often fragile, but using vdiffr means you will avoid all the problems we know how to avoid.
319319

320320
### Snapshotting values
321321

322322
`expect_snapshot()` is the most used snapshot function because it records everything: the code you run, printed output, messages, warnings, and errors.
323-
If you care about the return value rather than any side-effects, you might want to use `expect_snapshot_value()` instead.
324-
It offers a number of serialisation approaches that provide a tradeoff between accuracy and human readability.
323+
If you care about the return value rather than any side effects, you might want to use `expect_snapshot_value()` instead.
324+
It offers a number of serialization approaches that provide a tradeoff between accuracy and human readability.
325325

326326
```{r}
327327
test_that("can snapshot a simple list", {

vignettes/test-fixtures.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ message3 <- function(..., verbose = getOption("verbose")) {
271271
}
272272
```
273273

274-
Making external state explicit is often worthwhile, because it makes it more clear exactly what inputs determine the outputs of your function. But it's simply not possible in many cases. That's where test fixtures come in: they allow you to temporarily change global state in order to test your function. Test fixture is a pre-existing term in the software engineering world (and beyond):
274+
Making external state explicit is often worthwhile because it makes it clearer exactly what inputs determine the outputs of your function. But it's simply not possible in many cases. That's where test fixtures come in: they allow you to temporarily change global state to test your function. Test fixture is a pre-existing term in the software engineering world (and beyond):
275275

276276
> A test fixture is something used to consistently test some item, device, or piece of software.
277277
>
@@ -360,7 +360,7 @@ Setup code is typically best used to create external resources that are needed b
360360

361361
## Other challenges
362362

363-
A collection of miscellaneous problems that I don't know where else to describe:
363+
A collection of miscellaneous problems that don't fit elsewhere:
364364

365365
- There are a few base functions that are hard to test because they depend on state that you can't control. One such example is `interactive()`: there's no way to write a test fixture that allows you to pretend that interactive is either `TRUE` or `FALSE`. So we now usually use `rlang::is_interactive()` which can be controlled by the `rlang_interactive` option.
366366

0 commit comments

Comments
 (0)