1#include <exception>
2#include <stdexcept>
3#include <string>
4
5#include "cppunit/cppunit_proxy.h"
6
7#if defined (STLPORT) && defined (_STLP_USE_NAMESPACES)
8/*
9 * This test case purpose is to check that the exception handling
10 * functions are correctly imported to the STLport namespace only
11 * if they have a right behavior.
12 * Otherwise they are not imported to report the problem as a compile
13 * time error.
14 */
15
16//
17// TestCase class
18//
19class ExceptionTest : public CPPUNIT_NS::TestCase
20{
21  CPPUNIT_TEST_SUITE(ExceptionTest);
22#if defined (STLPORT) && !defined (_STLP_USE_EXCEPTIONS)
23  CPPUNIT_IGNORE;
24#endif
25  CPPUNIT_TEST(what);
26#if defined (STLPORT) && defined (_STLP_NO_UNEXPECTED_EXCEPT_SUPPORT)
27  CPPUNIT_IGNORE;
28#endif
29  CPPUNIT_TEST(unexpected_except);
30#if defined (STLPORT) && defined (_STLP_USE_EXCEPTIONS)
31  CPPUNIT_STOP_IGNORE;
32#endif
33#if defined (STLPORT) && defined (_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT)
34  CPPUNIT_IGNORE;
35#endif
36  CPPUNIT_TEST(uncaught_except);
37#if defined (STLPORT) && defined (_STLP_USE_EXCEPTIONS)
38  CPPUNIT_STOP_IGNORE;
39#endif
40  CPPUNIT_TEST(exception_emission);
41  CPPUNIT_TEST_SUITE_END();
42
43protected:
44  void what();
45  void unexpected_except();
46  void uncaught_except();
47  void exception_emission();
48};
49
50CPPUNIT_TEST_SUITE_REGISTRATION(ExceptionTest);
51
52#if !defined (STLPORT) || !defined (_STLP_NO_UNEXPECTED_EXCEPT_SUPPORT)
53bool g_unexpected_called = false;
54void unexpected_hdl() {
55  g_unexpected_called = true;
56  throw std::bad_exception();
57}
58
59struct special_except {};
60void throw_func() {
61  throw special_except();
62}
63
64void throw_except_func() throw(std::exception) {
65  throw_func();
66}
67#endif
68
69void ExceptionTest::what()
70{
71  try {
72    throw std::runtime_error( std::string( "message" ) );
73  }
74  catch ( std::runtime_error& err ) {
75    CPPUNIT_CHECK( strcmp( err.what(), "message" ) == 0 );
76  }
77}
78
79void ExceptionTest::unexpected_except()
80{
81#if !defined (STLPORT) || !defined (_STLP_NO_UNEXPECTED_EXCEPT_SUPPORT)
82  std::unexpected_handler hdl = &unexpected_hdl;
83  std::set_unexpected(hdl);
84
85  try {
86    throw_except_func();
87  }
88  catch (std::bad_exception const&) {
89    CPPUNIT_ASSERT( true );
90  }
91  catch (special_except) {
92    CPPUNIT_ASSERT( false );
93  }
94  CPPUNIT_ASSERT( g_unexpected_called );
95#endif
96}
97
98#if !defined (STLPORT) || !defined (_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT)
99struct UncaughtClassTest
100{
101  UncaughtClassTest(int &res) : _res(res)
102  {}
103
104  ~UncaughtClassTest() {
105    _res = std::uncaught_exception()?1:0;
106  }
107
108  int &_res;
109};
110#endif
111
112void ExceptionTest::uncaught_except()
113{
114#if !defined (STLPORT) || !defined (_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT)
115  int uncaught_result = -1;
116  {
117    UncaughtClassTest test_inst(uncaught_result);
118    CPPUNIT_ASSERT( uncaught_result == -1 );
119  }
120  CPPUNIT_ASSERT( uncaught_result == 0 );
121
122  {
123    try {
124      uncaught_result = -1;
125      UncaughtClassTest test_inst(uncaught_result);
126      throw "exception";
127    }
128    catch (...) {
129    }
130  }
131  CPPUNIT_ASSERT( uncaught_result == 1 );
132#endif
133}
134
135void ExceptionTest::exception_emission()
136{
137#if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
138  std::string foo = "foo";
139  try {
140    throw std::runtime_error(foo);
141  }
142  catch (std::runtime_error const& e) {
143    CPPUNIT_ASSERT( foo == e.what() );
144    std::runtime_error clone("");
145    clone = e;
146    CPPUNIT_ASSERT(foo == clone.what() );
147  }
148  catch (...) {
149    CPPUNIT_ASSERT( false );
150  }
151
152  try {
153    throw std::runtime_error(foo);
154  }
155  catch (std::runtime_error e) {
156    CPPUNIT_ASSERT( foo == e.what() );
157    std::runtime_error clone("");
158    clone = e;
159    CPPUNIT_ASSERT(foo == clone.what() );
160  }
161  catch (...) {
162    CPPUNIT_ASSERT( false );
163  }
164
165  std::string msg(512, 'a');
166  try {
167    throw std::runtime_error(msg);
168  }
169  catch (std::runtime_error const& e) {
170    CPPUNIT_ASSERT(msg == e.what() );
171    std::runtime_error clone("");
172    clone = e;
173    CPPUNIT_ASSERT(msg == clone.what() );
174  }
175  catch (...) {
176    CPPUNIT_ASSERT( false );
177  }
178
179  try {
180    throw std::runtime_error(msg);
181  }
182  catch (std::runtime_error e) {
183    CPPUNIT_ASSERT(msg == e.what() );
184    std::runtime_error clone("");
185    clone = e;
186    CPPUNIT_ASSERT(msg == clone.what() );
187  }
188  catch (...) {
189    CPPUNIT_ASSERT( false );
190  }
191#endif
192}
193#endif
194