Skip to content

Commit 7b71880

Browse files
authored
Implement expect_r6_class() (#2162)
Fixes #2030
1 parent f56ecfd commit 7b71880

File tree

6 files changed

+72
-0
lines changed

6 files changed

+72
-0
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export(expect_no_warning)
114114
export(expect_null)
115115
export(expect_output)
116116
export(expect_output_file)
117+
export(expect_r6_class)
117118
export(expect_reference)
118119
export(expect_s3_class)
119120
export(expect_s4_class)

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# testthat (development version)
22

3+
* New `expect_r6_class()` (#2030).
34
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
45
* `JunitReporter()` no longer fails with `"no applicable method for xml_add_child"` for warnings outside of tests (#1913). Additionally, warnings now save their backtraces.
56
* `JunitReporter()` strips ANSI escapes in more placese (#1852, #2032).

R/expect-inheritance.R

Lines changed: 23 additions & 0 deletions
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_r6_class(x, class)` checks that `x` an R6 object that
16+
#' inherits from `class`.
1517
#' * `expect_s7_class(x, Class)` checks that `x` is an S7 object that
1618
#' [S7::S7_inherits()] from `Class`
1719
#'
@@ -26,6 +28,7 @@
2628
#' `exact = TRUE`.
2729
#' * `expect_s4_class()`: a character vector of class names or `NA` to assert
2830
#' that `object` isn't an S4 object.
31+
#' * `expect_r6_class()`: a string.
2932
#' * `expect_s7_class()`: an [S7::S7_class()] object.
3033
#' @inheritParams expect_that
3134
#' @family expectations
@@ -154,6 +157,26 @@ expect_s4_class <- function(object, class) {
154157
pass(act$val)
155158
}
156159

160+
#' @export
161+
#' @rdname inheritance-expectations
162+
expect_r6_class <- function(object, class) {
163+
act <- quasi_label(enquo(object))
164+
check_string(class)
165+
166+
if (!inherits(act$val, "R6")) {
167+
return(fail(sprintf("%s is not an R6 object.", act$lab)))
168+
}
169+
170+
if (!inherits(act$val, class)) {
171+
act_class <- format_class(class(act$val))
172+
exp_class <- format_class(class)
173+
msg <- sprintf("%s inherits from %s not %s.", act$lab, act_class, exp_class)
174+
return(fail(msg))
175+
}
176+
177+
pass(act$val)
178+
}
179+
157180
#' @export
158181
#' @rdname inheritance-expectations
159182
expect_s7_class <- function(object, class) {

man/inheritance-expectations.Rd

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/expect-inheritance.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@
4747

4848
`x` inherits from 'a'/'b' not 'c'/'d'.
4949

50+
# expect_r6_class generates useful failures
51+
52+
`x` is not an R6 object.
53+
54+
# expect_r6_class validates its inputs
55+
56+
Code
57+
expect_r6_class(1, c("Person", "Student"))
58+
Condition
59+
Error in `expect_r6_class()`:
60+
! `class` must be a single string, not a character vector.
61+
5062
# can check with actual class
5163

5264
Foo() inherits from <Foo> not <Bar>.

tests/testthat/test-expect-inheritance.R

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,35 @@ test_that("expect_s3_class validates its inputs", {
8888
})
8989
})
9090

91+
# expect_r6_class --------------------------------------------------------
92+
93+
test_that("expect_r6_class succeeds when object inherits from expected class", {
94+
Person <- R6::R6Class("Person")
95+
Student <- R6::R6Class("Student", inherit = Person)
96+
97+
person <- Person$new()
98+
student <- Student$new()
99+
100+
expect_success(expect_r6_class(person, "Person"))
101+
expect_success(expect_r6_class(student, "Student"))
102+
expect_success(expect_r6_class(student, "Person"))
103+
})
104+
105+
test_that("expect_r6_class generates useful failures", {
106+
x <- 1
107+
person <- R6::R6Class("Person")$new()
108+
109+
expect_snapshot_failure({
110+
expect_r6_class(x, "Student")
111+
expect_r6_class(person, "Student")
112+
})
113+
})
114+
115+
test_that("expect_r6_class validates its inputs", {
116+
expect_snapshot(error = TRUE, {
117+
expect_r6_class(1, c("Person", "Student"))
118+
})
119+
})
91120

92121
# expect_s7_class --------------------------------------------------------
93122

0 commit comments

Comments
 (0)