Skip to content

Commit de9de38

Browse files
New check_value= for test() to ignore 'y' (#7844)
1 parent 1508915 commit de9de38

4 files changed

Lines changed: 19 additions & 16 deletions

File tree

R/test.data.table.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,8 @@ gc_mem = function() {
377377
# defers parsing to runtime, allowing the encoding check to run first and avoid source() warnings.
378378
utf8_check = function(test_str) identical(test_str, enc2native(test_str))
379379

380-
test = function(num, x, y=TRUE,
381-
error=NULL, warning=NULL, message=NULL, output=NULL, notOutput=NULL, ignore.warning=NULL,
380+
test = function(num, x, y=TRUE, ...,
381+
error=NULL, warning=NULL, message=NULL, output=NULL, notOutput=NULL, ignore.warning=NULL, check_value=TRUE,
382382
options=NULL, env=NULL,
383383
context=NULL, requires_utf8=FALSE, optimize=NULL) {
384384
# if optimization is provided, test across multiple optimization levels
@@ -442,7 +442,7 @@ test = function(num, x, y=TRUE,
442442
}
443443
# Usage:
444444
# i) tests that x equals y when both x and y are supplied, the most common usage
445-
# ii) tests that x is TRUE when y isn't supplied
445+
# ii) tests that x is TRUE when y isn't supplied, or ignores y entirely when check_value=FALSE
446446
# iii) if error is supplied, y should be missing and x is tested to result in an error message matching the pattern
447447
# iv) if warning is supplied, y is checked to equal x, and x should result in a warning message matching the pattern
448448
# v) if output is supplied, x is evaluated and printed and the output is checked to match the pattern
@@ -636,7 +636,7 @@ test = function(num, x, y=TRUE,
636636
# nocov end
637637
}
638638
}
639-
if (!fail && !length(error) && (!length(output) || !missing(y))) { # TODO test y when output=, too
639+
if (check_value && !fail && !length(error) && (!length(output) || !missing(y))) { # TODO test y when output=, too
640640
capture.output(y <- try(y, silent=TRUE)) # y might produce verbose output, just toss it
641641
if (inherits(x, c("Date", "POSIXct"))) storage.mode(x) <- "numeric"
642642
if (inherits(y, c("Date", "POSIXct"))) storage.mode(y) <- "numeric"

inst/tests/other.Rraw

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ if (loaded[["parallel"]]) {
225225
}
226226

227227
# example(":=", local=TRUE) triggered cedta==FALSE and then error, #2972
228-
test(14.1, {example(':=', package='data.table', local=TRUE, echo=FALSE); TRUE})
229-
test(14.2, {example('CJ', package='data.table', local=TRUE, echo=FALSE); TRUE})
228+
test(14.1, example(':=', package='data.table', local=TRUE, echo=FALSE), check_value=FALSE)
229+
test(14.2, example('CJ', package='data.table', local=TRUE, echo=FALSE), check_value=FALSE)
230230

231231
if (loaded[["sf"]]) { #2273
232232
DT = as.data.table(st_read(system.file("shape/nc.shp", package = "sf"), quiet=TRUE))

inst/tests/tests.Rraw

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11280,10 +11280,10 @@ attr(x, 'tzone') = NULL
1128011280
test(1765.1, print(IDateTime(x)), output=".*idate.*itime.*1: 2017-03-1[67]")
1128111281

1128211282
# test test's ignore.warning
11283-
test(1765.2, {warning("foo"); 4L}, 4L, ignore.warning="foo")
11284-
test(1765.3, {warning("foo"); 4L}, 4L, ignore.warning="Foo", warning="foo")
11285-
test(1765.4, {warning("foobar1"); warning("foobar2"); warning("FOO"); 4L}, 4L, ignore.warning="bar", warning="FOO")
11286-
test(1765.5, {warning("foobar1"); warning("foobar2"); warning("FOO"); 4L}, 4L, ignore.warning="2", warning=c("foobar1","FOO"))
11283+
test(1765.2, warning("foo"), ignore.warning="foo", check_value=FALSE)
11284+
test(1765.3, warning("foo"), ignore.warning="Foo", warning="foo", check_value=FALSE)
11285+
test(1765.4, {warning("foobar1"); warning("foobar2"); warning("FOO")}, ignore.warning="bar", warning="FOO", check_value=FALSE)
11286+
test(1765.5, {warning("foobar1"); warning("foobar2"); warning("FOO")}, ignore.warning="2", warning=c("foobar1","FOO"), check_value=FALSE)
1128711287

1128811288
# print(null.data.table()) should not output NULL as well, #1852
1128911289
test(1766, data.table(NULL), notOutput = "NULL$")
@@ -17219,7 +17219,7 @@ test(2186, DT[, if (TRUE) .(a=1L) else .(a=1L, b=2L)], DT,
1721917219

1722017220
# col.names='none' should apply when wrapping too, #4270
1722117221
DT = setDT(replicate(getOption('width'), 1, simplify = FALSE))
17222-
test(2187, {print(DT, col.names='none'); TRUE}, notOutput="V")
17222+
test(2187, print(DT, col.names='none'), notOutput="V", check_value=FALSE)
1722317223

1722417224
# fifelse now supports vector na arguments and coerces NA to other types, PR#4289
1722517225
test(2188.01, fifelse(c(TRUE, FALSE, TRUE, NA), 1L, 2L, 1.0), c(1, 2, 1, 1))
@@ -20657,7 +20657,7 @@ test(2304.099, copy(DT)[2L, let(L1=list(NULL), L2=list(NULL))], ans)
2065720657
test(2304.100, set(copy(DT), i=2L, j=c("L1", "L2"), value=list(list(NULL), list(NULL))), ans)
2065820658

2065920659
# the integer overflow in #6729 is only noticeable with UBSan
20660-
if (test_R.utils) test(2305, { fread(testDir("issue_6729.txt.bz2")); TRUE })
20660+
if (test_R.utils) test(2305, fread(testDir("issue_6729.txt.bz2")), check_value=FALSE)
2066120661

2066220662
if (exists("sort_by", "package:base")) {
2066320663
# sort_by.data.table
@@ -20691,7 +20691,7 @@ DT <- data.table(a = 1:2, b = 2:1)
2069120691
setindex(DT, b)
2069220692
# make sure that print(DT) doesn't warn due to the header missing index column types, #6806
2069320693
# can't use output= here because the print() call is outside withCallingHandlers(...)
20694-
test(2307, { capture.output(print(DT, class = TRUE, show.indices = TRUE)); TRUE })
20694+
test(2307, capture.output(print(DT, class = TRUE, show.indices = TRUE)), check_value=FALSE)
2069520695

2069620696
# fread with colClasses and keepLeadingZeros=TRUE #6851
2069720697
dt = data.table(date=as.IDate(c(NA, "2014-12-05")))
@@ -21667,9 +21667,9 @@ test(2370.4, yearmon("2016-08-03 01:02:03.45", format="character"), "2016M08")
2166721667
test(2370.5, yearmon(NA, format="character"), NA_character_)
2166821668

2166921669
# multiple expected/observed warnings in test() are printed on aligned lines, #7092
21670-
test(2371.1, test(0, {warning("a"); 2L}, 2L, warning=c("a", "b")), FALSE,
21670+
test(2371.1, test(0, warning("a"), warning=c("a", "b"), check_value=FALSE), FALSE,
2167121671
output="Test 0 produced 1 warnings but expected 2\nExpected: a\n b\nObserved: a")
21672-
test(2372.2, test(0, {warning("a"); warning("b"); 2L}, 2L, warning="a"), FALSE,
21672+
test(2372.2, test(0, {warning("a"); warning("b")}, warning="a", check_value=FALSE), FALSE,
2167321673
output="Test 0 produced 2 warnings but expected 1\nExpected: a\nObserved: a\n b")
2167421674

2167521675
# group-by on empty table works

man/test.Rd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,25 @@
55
An internal testing function used in \code{data.table} test scripts that are run by \code{\link{test.data.table}}.
66
}
77
\usage{
8-
test(num, x, y = TRUE,
8+
test(num, x, y = TRUE, ...,
99
error = NULL, warning = NULL, message = NULL,
1010
output = NULL, notOutput = NULL, ignore.warning = NULL,
11+
check_value = TRUE,
1112
options = NULL, env = NULL, context = NULL,
1213
requires_utf8 = FALSE, optimize = NULL)
1314
}
1415
\arguments{
1516
\item{num}{ A unique identifier for a test, helpful in identifying the source of failure when testing is not working. Currently, we use a manually-incremented system with tests formatted as \code{n.m}, where essentially \code{n} indexes an issue and \code{m} indexes aspects of that issue. For the most part, your new PR should only have one value of \code{n} (scroll to the end of \code{inst/tests/tests.Rraw} to see the next available ID) and then index the tests within your PR by increasing \code{m}. Note -- \code{n.m} is interpreted as a number, so \code{123.4} and \code{123.40} are actually the same -- please \code{0}-pad as appropriate. Test identifiers are checked to be in increasing order at runtime to prevent duplicates being possible. }
1617
\item{x}{ An input expression to be evaluated. }
1718
\item{y}{ Pre-defined value to compare to \code{x}, by default \code{TRUE}. }
19+
\item{...}{ Ignored; used to prevent providing subsequent arguments positionally. }
1820
\item{error}{ When you are testing behaviour of code that you expect to fail with an error, supply the expected error message to this argument. It is interpreted as a regular expression, so you can be abbreviated, but try to include the key portion of the error so as not to accidentally include a different error message. }
1921
\item{warning}{ Same as \code{error}, in the case that you expect your code to issue a warning. Note that since the code evaluates successfully, you should still supply \code{y}. }
2022
\item{message}{ Same as \code{warning} but expects \code{message} exception. }
2123
\item{output}{ If you are testing the printing/console output behaviour; e.g. with \code{verbose=TRUE} or \code{options(datatable.verbose=TRUE)}. Again, regex-compatible and case sensitive. }
2224
\item{notOutput}{ Or if you are testing that a feature does \emph{not} print particular console output. Case insensitive (unlike output) so that the test does not incorrectly pass just because the string is not found due to case. }
2325
\item{ignore.warning}{ A single character string. Any warnings emitted by \code{x} that contain this string are dropped. Remaining warnings are compared to the expected \code{warning} as normal. }
26+
\item{check_value}{ Logical, default \code{TRUE}. If \code{FALSE}, \code{y} is ignored entirely. Useful, for example, when writing a test that \code{x} doesn't error. }
2427
\item{options}{ A named list of options to set for the duration of the test. Any code evaluated during this call to \code{test()} (usually, \code{x}, or maybe \code{y}) will run with the named options set, and the original options will be restored on return. This is a named list since different options can have different types in general, but in typical usage, only one option is set at a time, in which case a named vector is also accepted. }
2528
\item{env}{ A named list of environment variables to set for the duration of the test, much like \code{options}. A list entry set to \code{NULL} will unset (i.e., \code{\link{Sys.unsetenv}}) the corresponding variable. }
2629
\item{context}{ String, default \code{NULL}. Used to provide context where this is useful, e.g. in a test run in a loop where we can't just search for the test number. }

0 commit comments

Comments
 (0)