Skip to content

Commit 4331513

Browse files
committed
Add tests
1 parent 65e502d commit 4331513

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

inst/unitTests/cpp/exceptions.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2+
//
3+
// dates.cpp: Rcpp R/C++ interface class library -- Date + Datetime tests
4+
//
5+
// Copyright (C) 2010 - 2013 Dirk Eddelbuettel and Romain Francois
6+
//
7+
// This file is part of Rcpp.
8+
//
9+
// Rcpp is free software: you can redistribute it and/or modify it
10+
// under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 2 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// Rcpp is distributed in the hope that it will be useful, but
15+
// WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21+
22+
#include <Rcpp.h>
23+
using namespace Rcpp;
24+
25+
// [[Rcpp::export]]
26+
double takeLog(double val) {
27+
if (val <= 0.0) {
28+
throw std::range_error("Inadmissible value");
29+
}
30+
return log(val);
31+
}
32+
33+
// [[Rcpp::export]]
34+
double takeLogRcpp(double val) {
35+
if (val <= 0.0) {
36+
throw Rcpp::exception("Inadmissible value");
37+
}
38+
return log(val);
39+
}
40+
41+
// [[Rcpp::export]]
42+
double takeLogRcppLocation(double val) {
43+
if (val <= 0.0) {
44+
throw Rcpp::exception("Inadmissible value", "exceptions.cpp", 44);
45+
}
46+
return log(val);
47+
}
48+
49+
double f1(double val) {
50+
return takeLogRcppLocation(val);
51+
}
52+
53+
// [[Rcpp::export]]
54+
double takeLogNested(double val) {
55+
return f1(val);
56+
}

inst/unitTests/runit.exceptions.R

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env r
2+
# -*- mode: R; tab-width: 4; -*-
3+
#
4+
# Copyright (C) 2010 - 2013 Dirk Eddelbuettel and Romain Francois
5+
#
6+
# This file is part of Rcpp.
7+
#
8+
# Rcpp is free software: you can redistribute it and/or modify it
9+
# under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 2 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# Rcpp is distributed in the hope that it will be useful, but
14+
# WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
20+
.runThisTest <- Sys.getenv("RunAllRcppTests") == "yes"
21+
22+
if (.runThisTest) {
23+
.setUp <- Rcpp:::unitTestSetup("exceptions.cpp")
24+
25+
test.stdException <- function() {
26+
27+
# Code works normally without an exception
28+
checkIdentical(takeLog(1L), log(1L))
29+
30+
# C++ exceptions are converted to R conditions
31+
condition <- tryCatch(takeLog(-1L), error = identity)
32+
33+
checkIdentical(condition$message, "Inadmissible value")
34+
checkIdentical(class(condition), c("std::range_error", "C++Error", "error", "condition"))
35+
36+
# C++ stack only available for Rcpp::exceptions
37+
checkTrue(is.null(condition$cppstack))
38+
39+
checkIdentical(condition$call, quote(takeLog(-1L)))
40+
}
41+
42+
43+
test.rcppException <- function() {
44+
45+
# Code works normally without an exception
46+
checkIdentical(takeLog(1L), log(1L))
47+
48+
# C++ exceptions are converted to R conditions
49+
condition <- tryCatch(takeLogRcpp(-1L), error = identity)
50+
51+
checkIdentical(condition$message, "Inadmissible value")
52+
checkIdentical(class(condition), c("Rcpp::exception", "C++Error", "error", "condition"))
53+
54+
checkTrue(!is.null(condition$cppstack))
55+
56+
checkIdentical(class(condition$cppstack), "Rcpp_stack_trace")
57+
58+
checkEquals(condition$call, quote(takeLogRcpp(-1L)))
59+
}
60+
61+
test.rcppExceptionLocation <- function() {
62+
63+
# Code works normally without an exception
64+
checkIdentical(takeLog(1L), log(1L))
65+
66+
# C++ exceptions are converted to R conditions
67+
condition <- tryCatch(takeLogRcppLocation(-1L), error = identity)
68+
69+
checkIdentical(condition$message, "Inadmissible value")
70+
checkIdentical(class(condition), c("Rcpp::exception", "C++Error", "error", "condition"))
71+
72+
checkTrue(!is.null(condition$cppstack))
73+
checkIdentical(class(condition$cppstack), "Rcpp_stack_trace")
74+
75+
checkIdentical(condition$cppstack$file, "exceptions.cpp")
76+
checkIdentical(condition$cppstack$line, 44L)
77+
78+
checkEquals(condition$call, quote(takeLogRcppLocation(-1L)))
79+
}
80+
81+
test.rcppExceptionLocation <- function() {
82+
83+
# Nested exceptions work the same way
84+
normal <- tryCatch(takeLogRcppLocation(-1L), error = identity)
85+
f1 <- function(x) takeLogNested(x)
86+
87+
nested <- tryCatch(f1(-1), error = identity)
88+
89+
# Message the same
90+
checkIdentical(normal$message, nested$message)
91+
92+
checkEquals(nested$call, quote(takeLogNested(x)))
93+
}
94+
95+
}

0 commit comments

Comments
 (0)