From b292e3ae57e7fec3f1b53a9e425e401654f172c8 Mon Sep 17 00:00:00 2001 From: riccardoporreca Date: Tue, 26 Jan 2021 00:46:11 +0100 Subject: [PATCH] Use a test helper to define the expected C++ error class (fixes #15) * This works around the fact that, in certain circumstances, we cannot rely on errors propagating with proper `std::invalid_argument` class / error message. See also RcppCore/Rcpp#972 --- tests/testthat/helper-invalid_argument.R | 34 ++++++++++++++++++++++++ tests/testthat/test-TRNG.Engine.R | 4 +-- tests/testthat/test-TRNG.Random.R | 4 +-- 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 tests/testthat/helper-invalid_argument.R diff --git a/tests/testthat/helper-invalid_argument.R b/tests/testthat/helper-invalid_argument.R new file mode 100644 index 0000000..6be352c --- /dev/null +++ b/tests/testthat/helper-invalid_argument.R @@ -0,0 +1,34 @@ +# Work around the fact that, in certain circumstances (architectures / +# compilers), we cannot rely on errors propagating with proper +# `std::invalid_argument` class / error message. +# +# See https://github.com/miraisolutions/rTRNG/issues/15, +# https://github.com/RcppCore/Rcpp/issues/972 +# +# Approach: Use a minimal example to test whether "std::invalid_argument" is +# correctly detected, otherwise just fall-back on "error" (the "c++ exception +# (unknown reason)" error inherits from it). + +invalid_argument_thrower <- cppFunction(' + void invalid_argument_thrower() { + throw std::invalid_argument("Invalid argument test"); + } +') + +invalid_argument_error_class <- function() { + error_class <- tryCatch( + invalid_argument_thrower(), + error = function(e) class(e) + ) + error_class +} + +supported_invalid_argument_class <- function() { + if ("std::invalid_argument" %in% invalid_argument_error_class()) { + "std::invalid_argument" + } else { + "error" + } +} + +expected_invalid_argument_class <- supported_invalid_argument_class() diff --git a/tests/testthat/test-TRNG.Engine.R b/tests/testthat/test-TRNG.Engine.R index b4c4e44..5190b66 100644 --- a/tests/testthat/test-TRNG.Engine.R +++ b/tests/testthat/test-TRNG.Engine.R @@ -262,11 +262,11 @@ test_that("$split errors for out-of-range subsequence indices", { p <- 5L if (!grepl("(lagfib|mt)", engineClass)) { expect_error( - e$split(p, 0L), class = "std::invalid_argument", # 1-base indexing + e$split(p, 0L), class = expected_invalid_argument_class, # 1-base indexing info = .name(engineClass) ) expect_error( - e$split(p, p + 1L), class = "std::invalid_argument", + e$split(p, p + 1L), class = expected_invalid_argument_class, info = .name(engineClass) ) expect_error( diff --git a/tests/testthat/test-TRNG.Random.R b/tests/testthat/test-TRNG.Random.R index e415f86..19ace80 100644 --- a/tests/testthat/test-TRNG.Random.R +++ b/tests/testthat/test-TRNG.Random.R @@ -131,8 +131,8 @@ test_that("TRNGsplit errors for out-of-range subsequence indices", { TRNGkind(KIND) TRNGseed(SEED) p <- 5L - expect_error(TRNGsplit(p, 0L), class = "std::invalid_argument") # 1-base indexing - expect_error(TRNGsplit(p, p + 1L), class = "std::invalid_argument") + expect_error(TRNGsplit(p, 0L), class = expected_invalid_argument_class) # 1-base indexing + expect_error(TRNGsplit(p, p + 1L), class = expected_invalid_argument_class) expect_error(TRNGsplit(p, -1L), "negative") expect_error(TRNGsplit(-1L, 1L), "negative") })