1 #include <stan/io/program_reader.hpp>
2 #include <stan/model/rethrow_located.hpp>
3 #include <gtest/gtest.h>
4 
stub_reader()5 stan::io::program_reader stub_reader() {
6   stan::io::program_reader r;
7   r.add_event(0, 0, "start", "/Users/carp/temp2/foo.stan");
8   r.add_event(5, 5, "include", "/Users/carp/temp2/bar.stan");
9   r.add_event(5, 0, "start", "/Users/carp/temp2/bar.stan");
10   r.add_event(8, 3, "end", "/Users/carp/temp2/bar.stan");
11   r.add_event(8, 6, "restart", "/Users/carp/temp2/foo.stan");
12   r.add_event(9, 7, "end", "/Users/carp/temp2/foo.stan");
13   return r;
14 }
15 
16 template <typename E, typename E2>
test_rethrow_located_2()17 void test_rethrow_located_2() {
18   try {
19     try {
20       throw E("foo");
21     } catch (const std::exception& e) {
22       stan::io::program_reader reader = stub_reader();
23       stan::lang::rethrow_located(e, 5, reader);
24     }
25   } catch (const E2& e) {
26     EXPECT_TRUE(std::string(e.what()).find_first_of("5") != std::string::npos);
27     EXPECT_TRUE(std::string(e.what()).find_first_of("foo")
28                 != std::string::npos);
29     return;
30   } catch (...) {
31     FAIL();
32   }
33   FAIL();
34 }
35 
36 template <typename E>
test_rethrow_located()37 void test_rethrow_located() {
38   test_rethrow_located_2<E, E>();
39 }
40 
41 template <typename E>
test_rethrow_located_nullary(const std::string & original_type)42 void test_rethrow_located_nullary(const std::string& original_type) {
43   try {
44     try {
45       throw E();
46     } catch (const std::exception& e) {
47       stan::io::program_reader reader = stub_reader();
48       stan::lang::rethrow_located(e, 5, reader);
49     }
50   } catch (const E& e) {
51     EXPECT_TRUE(std::string(e.what()).find_first_of("5") != std::string::npos);
52     EXPECT_TRUE(std::string(e.what()).find_first_of(original_type)
53                 != std::string::npos);
54     return;
55   } catch (...) {
56     FAIL();
57   }
58   FAIL();
59 }
60 
61 struct my_test_exception : public std::exception {
62   const std::string what_;
my_test_exceptionmy_test_exception63   my_test_exception(const std::string& what) throw() : what_(what) {}
~my_test_exceptionmy_test_exception64   ~my_test_exception() throw() {}
whatmy_test_exception65   const char* what() const throw() { return what_.c_str(); }
66 };
67 
TEST(langRethrowLocated,allExpected)68 TEST(langRethrowLocated, allExpected) {
69   test_rethrow_located_nullary<std::bad_alloc>("bad_alloc");
70   test_rethrow_located_nullary<std::bad_cast>("bad_cast");
71   test_rethrow_located_nullary<std::bad_exception>("bad_exception");
72   test_rethrow_located_nullary<std::bad_typeid>("bad_typeid");
73 
74   test_rethrow_located<std::domain_error>();
75   test_rethrow_located<std::invalid_argument>();
76   test_rethrow_located<std::length_error>();
77   test_rethrow_located<std::out_of_range>();
78   test_rethrow_located<std::logic_error>();
79   test_rethrow_located<std::overflow_error>();
80   test_rethrow_located<std::range_error>();
81   test_rethrow_located<std::underflow_error>();
82   test_rethrow_located<std::runtime_error>();
83 
84   test_rethrow_located_nullary<std::exception>("std::exception");
85   test_rethrow_located_2<my_test_exception, std::exception>();
86 }
TEST(langRethrowLocated,locatedException)87 TEST(langRethrowLocated, locatedException) {
88   // tests nested case
89   using stan::lang::located_exception;
90   try {
91     try {
92       throw located_exception<located_exception<std::exception> >("foo", "bar");
93     } catch (const std::exception& e) {
94       stan::io::program_reader reader = stub_reader();
95       stan::lang::rethrow_located(e, 5, reader);
96     }
97   } catch (const std::exception& e) {
98     EXPECT_TRUE(std::string(e.what()).find_first_of("foo")
99                 != std::string::npos);
100     EXPECT_TRUE(std::string(e.what()).find_first_of("bar")
101                 != std::string::npos);
102     EXPECT_TRUE(std::string(e.what()).find_first_of("5") != std::string::npos);
103     return;
104   } catch (...) {
105     FAIL();
106   }
107   FAIL();
108 }
109