-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend expect_length to use an S4 object's length method, if exists #564
Conversation
R/expect-length.R
Outdated
@@ -15,8 +15,8 @@ expect_length <- function(object, n) { | |||
stopifnot(is.numeric(n), length(n) == 1) | |||
lab <- label(object) | |||
|
|||
if (!is_vector(object)) { | |||
fail(sprintf("%s is not a vector.", lab)) | |||
if (!has_length(object)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather simply remove this check all together. Would you mind doing that?
Check removed. |
tests/testthat/test-expect-length.R
Outdated
# Default for S4 objects that don't inherit a length method: always length 1 | ||
expect_success(expect_length(A(x=1:5, y=3), 1)) | ||
|
||
# B does has a length method defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly tests of the implementation of length()
. I think you only need the test for ExpectLengthB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests pruned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good - last thing is to add a bullet to NEWS briefly describing the change and crediting yourself.
Thanks! |
No, thank you! |
expect_length
is a clean, convenient shortcut forexpect_equal(length(x), n)
, but in its current implementation, only objects that are one of R's internal array types are whitelisted. An S4 object that doesn't inherit from one of those types is forbidden, even if it has alength
method defined. Aside from the inconvenience of having to fall back toexpect_equal
, this limitation increases the chances of writing a misleading test because, as?length
says, "[a]ll other objects (including functions) have length one."This pull request extends
expect_length
to work with S4 objects that have a length method. The additional check examines whetherselectMethod
selects the default.Primitive("length")
(which always returns 1) for an S4 object. If a length method other than the primitive is set or inherited,expect_length
will proceed. Other seemingly more natural ways of checking for the existence of a method don't work:existsMethod
doesn't follow inheritance andhasMethod
always returnsTRUE
for S4 objects because the primitive method is found.This pull request also contains a commit that updates the junit test fixture for what I am guessing is a change in the 'xml2' package. When I reset my fork to upstream/master, it failed on Travis. I suspect an 'xml2' change caused the failure because the most recent release of that package was after the most recent commit to the master branch of 'testthat'.