Skip to content

Commit ded433f

Browse files
authored
S7 improvements (#1853)
* Fix error when `@prop` had mismatched braces. * Make sure `method(generic, class)` works when `generic` is S3 or S4. * Add tests for classes with package set, and improve the output file name.
1 parent 664a828 commit ded433f

7 files changed

Lines changed: 64 additions & 1 deletion

File tree

R/object-from-call.R

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,12 @@ parser_s7_method <- function(call, env, block) {
245245
method_call <- call[[3]]
246246

247247
generic <- eval(generic_call, env)
248-
generic_name <- generic@name
248+
if (inherits(generic, "S7_generic")) {
249+
generic_name <- generic@name
250+
} else {
251+
# S3 or S4 generic passed by name
252+
generic_name <- deparse(generic_call)
253+
}
249254

250255
# Evaluate class spec: either a single class, a union, or list() for
251256
# multi-dispatch

R/rd-s7.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#' @export
22
roxy_tag_parse.roxy_tag_prop <- function(x) {
33
x <- tag_two_part(x, "a property name", "a description")
4+
if (is.null(x)) {
5+
return()
6+
}
47

58
# Optionally specify a class
69
if (grepl("@", x$val$name, fixed = TRUE)) {

R/utils.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ subs <- c(
1414
"[<-" = "-subset-",
1515
"[" = "-sub-",
1616
"<-" = "-set-",
17+
"::" = "-",
1718

1819
# Infix verbs
1920
"!" = "-not-",

tests/testthat/_snaps/rd-s7.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535
}
3636
3737

38+
# @prop with mismatched braces warns and doesn't crash
39+
40+
Code
41+
. <- roc_proc_text(rd_roclet(), text)
42+
Message
43+
x <text>:4: @prop has mismatched braces or quotes.
44+
3845
# @prop class@name warns on invalid spec
3946

4047
Code

tests/testthat/test-object-from-call.R

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,38 @@ test_that("S7 non-union method has no extra aliases", {
295295
expect_null(obj$alias)
296296
})
297297

298+
test_that("finds S7 methods for S3 generics", {
299+
skip_unless_r(">= 4.3.0")
300+
obj <- call_to_object({
301+
Dog <- S7::new_class("Dog")
302+
S7::method(print, Dog) <- function(x, ...) cat("Dog\n")
303+
})
304+
expect_s3_class(obj, "s7method")
305+
expect_equal(obj$topic, "print,Dog-method")
306+
expect_equal(obj$value$generic, "print")
307+
})
308+
309+
test_that("S7 method topic includes package prefix in class name", {
310+
skip_unless_r(">= 4.3.0")
311+
obj <- call_to_object({
312+
Dog <- S7::new_class("Dog", package = "mypkg")
313+
speak <- S7::new_generic("speak", "x")
314+
S7::method(speak, Dog) <- function(x) "Woof"
315+
})
316+
expect_equal(obj$topic, "speak,mypkg::Dog-method")
317+
expect_equal(obj$value$classes, list("mypkg::Dog"))
318+
})
319+
320+
test_that("S7 method on S3 generic includes package prefix in class name", {
321+
skip_unless_r(">= 4.3.0")
322+
obj <- call_to_object({
323+
Dog <- S7::new_class("Dog", package = "mypkg")
324+
S7::method(print, Dog) <- function(x, ...) cat("Dog\n")
325+
})
326+
expect_equal(obj$topic, "print,mypkg::Dog-method")
327+
expect_equal(obj$value$generic, "print")
328+
})
329+
298330
test_that("S7 method with unknown class type warns", {
299331
skip_unless_r(">= 4.3.0")
300332
block <- roxy_block(tags = list(), file = "test.R", line = 1, call = quote(x))

tests/testthat/test-rd-s7.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ test_that("@prop class@name groups by class", {
3030
expect_snapshot(out$get_section("prop"))
3131
})
3232

33+
test_that("@prop with mismatched braces warns and doesn't crash", {
34+
text <- "
35+
#' A class.
36+
#'
37+
#' @prop a prop a
38+
#' }
39+
a <- function() {}
40+
"
41+
expect_snapshot(. <- roc_proc_text(rd_roclet(), text))
42+
})
43+
3344
test_that("@prop class@name warns on invalid spec", {
3445
text <- "
3546
#' A class.

tests/testthat/test-utils.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ test_that("nice_name protects against invalid characters", {
88
expect_equal(nice_name("[.a"), "sub-.a")
99
})
1010

11+
test_that("nice_name strips ::", {
12+
expect_equal(nice_name("print,pkg::Class-method"), "print-pkg-Class-method")
13+
})
14+
1115
test_that("is_namespaced works as expected", {
1216
expect_true(is_namespaced("a::b"))
1317
expect_false(is_namespaced("b::"))

0 commit comments

Comments
 (0)