Skip to content

Commit 2068510

Browse files
committed
test(options=...) applies them for a shorter time
Instead of applying passed options= for the rest of the call frame, undo them immediately after evaluating the call. This prevents testing for options(datatable.alloccol=...) from breaking the internal data.table usage and allows rewriting the tests using the options=... and error=... arguments, which skip tests as appropriate in foreign mode.
1 parent 78c3f7c commit 2068510

File tree

2 files changed

+20
-39
lines changed

2 files changed

+20
-39
lines changed

R/test.data.table.R

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,10 +336,6 @@ test = function(num,x,y=TRUE,error=NULL,warning=NULL,message=NULL,output=NULL,no
336336
Sys.unsetenv(names(old)[!is_preset])
337337
}, add=TRUE)
338338
}
339-
if (!is.null(options)) {
340-
old_options <- do.call(base::options, as.list(options)) # as.list(): allow passing named character vector for convenience
341-
on.exit(base::options(old_options), add=TRUE)
342-
}
343339
# Usage:
344340
# i) tests that x equals y when both x and y are supplied, the most common usage
345341
# ii) tests that x is TRUE when y isn't supplied
@@ -425,13 +421,21 @@ test = function(num,x,y=TRUE,error=NULL,warning=NULL,message=NULL,output=NULL,no
425421
actual$message <- c(actual$message, conditionMessage(m))
426422
m
427423
}
424+
if (!is.null(options)) {
425+
old_options <- do.call(base::options, as.list(options)) # as.list(): allow passing named character vector for convenience
426+
on.exit(base::options(old_options), add=TRUE)
427+
}
428428
if (is.null(output) && is.null(notOutput)) {
429429
x = suppressMessages(withCallingHandlers(tryCatch(x, error=eHandler), warning=wHandler, message=mHandler))
430430
# save the overhead of capture.output() since there are a lot of tests, often called in loops
431431
# Thanks to tryCatch2 by Jan here : https://github.com/jangorecki/logR/blob/master/R/logR.R#L21
432432
} else {
433433
out = capture.output(print(x <- suppressMessages(withCallingHandlers(tryCatch(x, error=eHandler), warning=wHandler, message=mHandler))))
434434
}
435+
if (!is.null(options)) {
436+
base::options(old_options)
437+
old_options <- list()
438+
}
435439
fail = FALSE
436440
if (.test.data.table && num>0.0) {
437441
if (num<prevtest+0.0000005) {

inst/tests/tests.Rraw

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,43 +1361,20 @@ if (test_bit64) {
13611361
test(431.5, DT[5,1:=as.integer64(NA)], data.table(a=factor(c(NA,NA,NA,NA,NA), levels=LETTERS[1:3]), b=1:5))
13621362
}
13631363

1364-
old = getOption("datatable.alloccol") # Test that unsetting datatable.alloccol is caught, #2014
1365-
options(datatable.alloccol=NULL) # In this =NULL case, options() in R 3.0.0 returned TRUE rather than the old value. This R bug was fixed in R 3.1.1.
1366-
# This is why getOption is called first rather than just using the result of option() like elsewhere in this test file.
1367-
# TODO: simplify this test if/when R dependency >= 3.1.1
1368-
err1 = try(data.table(a=1:3), silent=TRUE)
1369-
options(datatable.alloccol="1024")
1370-
err2 = try(data.table(a=1:3), silent=TRUE)
1371-
options(datatable.alloccol=c(10L,20L))
1372-
err3 = try(data.table(a=1:3), silent=TRUE)
1373-
options(datatable.alloccol=NA_integer_)
1374-
err4 = try(data.table(a=1:3), silent=TRUE)
1375-
options(datatable.alloccol=-1)
1376-
err5 = try(data.table(a=1:3), silent=TRUE)
1377-
options(datatable.alloccol=1024L) # otherwise test() itself fails in its internals with the alloc.col error
1378-
test(432.1, inherits(err1,"try-error") && grep("Has getOption[(]'datatable.alloccol'[)] somehow become unset?", err1))
1379-
test(432.2, inherits(err2,"try-error") && grep("getOption[(]'datatable.alloccol'[)] should be a number, by default 1024. But its type is 'character'.", err2))
1380-
test(432.3, inherits(err3,"try-error") && grep("is a numeric vector ok but its length is 2. Its length should be 1.", err3))
1381-
test(432.4, inherits(err4,"try-error") && grep("It must be >=0 and not NA.", err4))
1382-
test(432.5, inherits(err5,"try-error") && grep("It must be >=0 and not NA.", err5))
1364+
# Test that unsetting datatable.alloccol is caught, #2014
1365+
test(432.1, data.table(a=1:3), options=list(datatable.alloccol=NULL), error="Has getOption[(]'datatable.alloccol'[)] somehow become unset?")
1366+
test(432.2, data.table(a=1:3), options=c(datatable.alloccol="1024"), error="getOption[(]'datatable.alloccol'[)] should be a number, by default 1024. But its type is 'character'.")
1367+
test(432.3, data.table(a=1:3), options=list(datatable.alloccol=c(10L,20L)), error="is a numeric vector ok but its length is 2. Its length should be 1.")
1368+
test(432.4, data.table(a=1:3), options=c(datatable.alloccol=NA_integer_), error="It must be >=0 and not NA.")
1369+
test(432.5, data.table(a=1:3), options=c(datatable.alloccol=-1), error="It must be >=0 and not NA.")
1370+
13831371
# Repeat the tests but this time with subsetting, to ensure the validity check on option happens for those too
13841372
DT = data.table(a=1:3, b=4:6)
1385-
options(datatable.alloccol=NULL)
1386-
err1 = try(DT[2,], silent=TRUE)
1387-
options(datatable.alloccol="1024")
1388-
err2 = try(DT[,2], silent=TRUE)
1389-
options(datatable.alloccol=c(10L,20L))
1390-
err3 = try(DT[a>1], silent=TRUE)
1391-
options(datatable.alloccol=NA_integer_)
1392-
err4 = try(DT[,"b"], silent=TRUE)
1393-
options(datatable.alloccol=-1)
1394-
err5 = try(DT[2,"b"], silent=TRUE)
1395-
options(datatable.alloccol=1024L) # otherwise test() itself fails in its internals with the alloc.col error
1396-
test(433.1, inherits(err1,"try-error") && grep("Has getOption[(]'datatable.alloccol'[)] somehow become unset?", err1))
1397-
test(433.2, inherits(err2,"try-error") && grep("getOption[(]'datatable.alloccol'[)] should be a number, by default 1024. But its type is 'character'.", err2))
1398-
test(433.3, inherits(err3,"try-error") && grep("is a numeric vector ok but its length is 2. Its length should be 1.", err3))
1399-
test(433.4, inherits(err4,"try-error") && grep("It must be >=0 and not NA.", err4))
1400-
test(433.5, inherits(err5,"try-error") && grep("It must be >=0 and not NA.", err5))
1373+
test(433.1, DT[2,], options=list(datatable.alloccol=NULL), error="Has getOption[(]'datatable.alloccol'[)] somehow become unset?")
1374+
test(433.2, DT[,2], options=c(datatable.alloccol="1024"), error="getOption[(]'datatable.alloccol'[)] should be a number, by default 1024. But its type is 'character'.")
1375+
test(433.3, DT[a>1], options=list(datatable.alloccol=c(10L,20L)), error="is a numeric vector ok but its length is 2. Its length should be 1.")
1376+
test(433.4, DT[,"b"], options=c(datatable.alloccol=NA_integer_), error="It must be >=0 and not NA.")
1377+
test(433.5, DT[2,"b"], options=c(datatable.alloccol=-1), error="It must be >=0 and not NA.")
14011378

14021379
# simple realloc test
14031380
DT = data.table(a=1:3,b=4:6)

0 commit comments

Comments
 (0)