Skip to content

Commit fc0025c

Browse files
authored
Implement expect_S7_class() (#2017)
Fixes #1580. Closes #2016.
1 parent 5a8200a commit fc0025c

File tree

7 files changed

+70
-1
lines changed

7 files changed

+70
-1
lines changed

DESCRIPTION

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Suggests:
4343
knitr,
4444
rmarkdown,
4545
rstudioapi,
46+
S7,
4647
shiny,
4748
usethis,
4849
vctrs (>= 0.1.0),

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ export(expect_output_file)
117117
export(expect_reference)
118118
export(expect_s3_class)
119119
export(expect_s4_class)
120+
export(expect_s7_class)
120121
export(expect_setequal)
121122
export(expect_silent)
122123
export(expect_snapshot)

NEWS.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# testthat (development version)
22

3+
* New `expect_s7_class()` for testing if an object is an S7 class (#1580).
34
* `expect_error()` and friends now error if you supply `...` but not `pattern` (#1932).
45
* New `expect_no_failure()`, `expect_no_success()` and `expect_snapshot_failure()` provide more options for testing expectations.
56
* `expect_error()` and friends no longer give an uninformative error if they fail inside a magrittr pipe (#1994).

R/expect-inheritance.R

+29
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#' * `expect_s4_class(x, class)` checks that `x` is an S4 object that
1313
#' [is()] `class`.
1414
#' * `expect_s4_class(x, NA)` checks that `x` isn't an S4 object.
15+
#' * `expect_s7_class(x, Class)` checks that `x` is an S7 object that
16+
#' [S7::S7_inherits()] from `Class`
1517
#'
1618
#' See [expect_vector()] for testing properties of objects created by vctrs.
1719
#'
@@ -92,6 +94,33 @@ expect_s3_class <- function(object, class, exact = FALSE) {
9294
invisible(act$val)
9395
}
9496

97+
#' @export
98+
#' @rdname inheritance-expectations
99+
expect_s7_class <- function(object, class) {
100+
check_installed("S7")
101+
if (!inherits(class, "S7_class")) {
102+
stop_input_type(class, "an S7 class object")
103+
}
104+
105+
act <- quasi_label(enquo(object), arg = "object")
106+
107+
if (!S7::S7_inherits(object)) {
108+
fail(sprintf("%s is not an S7 object", act$lab))
109+
} else {
110+
expect(
111+
S7::S7_inherits(object, class),
112+
sprintf(
113+
"%s inherits from %s not <%s>.",
114+
act$lab,
115+
paste0("<", setdiff(base::class(object), "S7_object"), ">", collapse = "/"),
116+
attr(class, "name", TRUE)
117+
)
118+
)
119+
}
120+
121+
invisible(act$val)
122+
}
123+
95124
#' @export
96125
#' @rdname inheritance-expectations
97126
expect_s4_class <- function(object, class) {

man/inheritance-expectations.Rd

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/expect-inheritance.md

+16
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,19 @@
1818

1919
`x` inherits from 'a'/'b' not 'c'/'d'.
2020

21+
# checks its inputs
22+
23+
Code
24+
expect_s7_class(1, 1)
25+
Condition
26+
Error in `expect_s7_class()`:
27+
! `class` must be an S7 class object, not the number 1.
28+
29+
# can check with actual class
30+
31+
Foo() inherits from <Foo> not <Bar>.
32+
33+
---
34+
35+
Baz() inherits from <Baz>/<Foo> not <Bar>.
36+

tests/testthat/test-expect-inheritance.R

+17-1
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,24 @@ test_that("test_s3_class can request exact match", {
5656
expect_success(expect_s3_class(x, c("a", "b"), exact = TRUE))
5757
})
5858

59-
6059
test_that("expect_s3_class allows unquoting of first argument", {
6160
f <- factor("a")
6261
expect_success(expect_s3_class(!! rlang::quo(f), "factor"))
6362
})
63+
64+
65+
# expect_s7_class --------------------------------------------------------
66+
67+
test_that("checks its inputs", {
68+
expect_snapshot(expect_s7_class(1, 1), error = TRUE)
69+
})
70+
71+
test_that("can check with actual class", {
72+
Foo <- S7::new_class("Foo")
73+
Bar <- S7::new_class("Bar")
74+
expect_success(expect_s7_class(Foo(), class = Foo))
75+
expect_snapshot_failure(expect_s7_class(Foo(), class = Bar))
76+
77+
Baz <- S7::new_class("Baz", parent = Foo)
78+
expect_snapshot_failure(expect_s7_class(Baz(), class = Bar))
79+
})

0 commit comments

Comments
 (0)