tests/testthat/test-object-s3.R

test_that("primitive generics detected", {
  expect_true(is_s3_generic("["))
  expect_true(is_s3_method("[.data.frame"))

  expect_true(is_s3_generic("mean"))
  expect_true(is_s3_method("mean.default"))

  expect_true(is_s3_generic("c"))
  expect_true(is_s3_method("c.Date"))
})

test_that("non-functions are not generics", {
  a <- TRUE
  b <- NULL

  expect_false(is_s3_generic("a"))
  expect_false(is_s3_generic("b"))
})

test_that("ignores non-function objects when looking for generics", {
  c <- data.frame()
  expect_true(is_s3_generic("c"))
})

test_that("user defined generics & methods detected", {
  my_method <- function(x) UseMethod("mymethod")
  my_method.character <- function(x) x

  expect_true(is_s3_generic("my_method"))
  expect_true(is_s3_method("my_method.character"))
})

test_that("methods for group generics detected", {
  Ops.myclass <- function(x) x

  expect_false(is_s3_generic("Ops.myclass"))
  expect_true(is_s3_method("Ops.myclass"))
})

test_that("user defined generics detected even if use non-standard", {
  my_method <- function(x) {
    x <- 1
    if (x > 2) UseMethod("mymethod")
  }

  expect_true(is_s3_generic("my_method"))
})

test_that("S4 generics are not treated as S3 methods", {
  env <- new.env(parent = globalenv())
  env$all.equal <- {
    methods::setGeneric("all.equal")
    all.equal
  }
  on.exit(methods::removeGeneric("all.equal"), add = TRUE)

  expect_false(is_s3_method("all.equal", env))
})

test_that("all.equal is matched correctly", {
  expect_equal(find_generic("all.equal.numeric"), c("all.equal", "numeric"))
  expect_equal(
    find_generic("all.equal.data.frame"),
    c("all.equal", "data.frame")
  )
})

test_that("user defined functions override primitives", {
  c <- function(x) x + 1
  c.test <- function(x) x + 3

  expect_false(is_s3_generic("c"))
  expect_false(is_s3_method("c"))
})

Try the roxygen2 package in your browser

Any scripts or data that you put into this service are public.

roxygen2 documentation built on Aug. 5, 2026, 1:06 a.m.