You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes for test.data.table() in foreign mode (#6808)
* test.data.table(): don't test non-English output
This is already done for warnings and errors. Unfortunately, some tests
do check output and conditions by hand, so test.data.table() still
requires LANGUAGE=en for now.
* Use test(output=) instead of capture.output()
A comment near 1832.2 said that output= was inapplicable due to square
bracket matching. The actual source of the problem was the caret only
matching start of string instead of start of line.
* Use output= for some all.equal tests
While not all all.equal() output is translated, those cases that are
result in test failures when comparing the output in test() calls. Use
output= so that the test would be skipped in 'foreign' mode.
* Don't count foreign warnings when skipping some
We already only count warnings in foreign mode, don't match their text
contents. With ignore.warning set, we lack a way to figure out when the
translated warning should be skipped, so don't count them at all.
* Also skip notOutput= tests in foreign mode
The length(output) || length(notOutput) branch makes length(output) at
least 1. Later, 'y' value check is skipped if length(output) is nonzero.
Instead of skipping this branch altogether in foreign mode, make sure
that it's taken so that the 'y' value check is later skipped when
foreign mode is on.
* 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.
* remove regex mark-up for clarity
* rm regex again
* ws style
* check !foreign before attempting string_match()
* ditto
* Elaborate on the use of options()
---------
Co-authored-by: Michael Chirico <[email protected]>
for (msginignore.warning) observed= grep(msg, observed, value=TRUE, invert=TRUE) # allow multiple for translated messages rather than relying on '|' to always work
456
462
}
457
-
if (length(expected) != length(observed)) {
463
+
if (length(expected) != length(observed)&& (!foreign|| is.null(ignore.warning))) {
458
464
# nocov start
459
465
catf("Test %s produced %d %ss but expected %d\n%s\n%s\n", numStr, length(observed), type, length(expected), paste("Expected:", expected), paste("Observed:", observed, collapse="\n"))
460
466
fail=TRUE
461
467
# nocov end
462
-
} else {
468
+
} elseif (!foreign) {
463
469
# the expected type occurred and, if more than 1 of that type, in the expected order
464
470
for (iin seq_along(expected)) {
465
-
if (!foreign&&!string_match(expected[i], observed[i])) {
471
+
if (!string_match(expected[i], observed[i])) {
466
472
# nocov start
467
473
catf("Test %s didn't produce the correct %s:\nExpected: %s\nObserved: %s\n", numStr, type, expected[i], observed[i])
468
474
fail=TRUE
@@ -481,7 +487,8 @@ test = function(num,x,y=TRUE,error=NULL,warning=NULL,message=NULL,output=NULL,no
481
487
if (out[length(out)] =="NULL") out=out[-length(out)]
482
488
out= paste(out, collapse="\n")
483
489
output= paste(output, collapse="\n") # so that output= can be either a \n separated string, or a vector of strings.
484
-
if (length(output) &&!string_match(output, out)) {
490
+
# it also happens to turn off the 'y' checking branch below
491
+
if (length(output) &&!foreign&&!string_match(output, out)) {
485
492
# nocov start
486
493
catf("Test %s did not produce correct output:\n", numStr)
487
494
catf("Expected: <<%s>>\n", encodeString(output)) # \n printed as '\\n' so the two lines of output can be compared vertically
@@ -493,7 +500,7 @@ test = function(num,x,y=TRUE,error=NULL,warning=NULL,message=NULL,output=NULL,no
493
500
fail=TRUE
494
501
# nocov end
495
502
}
496
-
if (length(notOutput) && string_match(notOutput, out, ignore.case=TRUE)) {
503
+
if (length(notOutput) &&!foreign&&string_match(notOutput, out, ignore.case=TRUE)) {
497
504
# nocov start
498
505
catf("Test %s produced output but should not have:\n", numStr)
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
+
1383
1371
# Repeat the tests but this time with subsetting, to ensure the validity check on option happens for those too
1384
1372
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.")
0 commit comments