1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/base/internal/throw_delegate.h"
16 
17 #include <functional>
18 #include <new>
19 #include <stdexcept>
20 
21 #include "absl/base/config.h"
22 #include "gtest/gtest.h"
23 
24 namespace {
25 
26 using absl::base_internal::ThrowStdLogicError;
27 using absl::base_internal::ThrowStdInvalidArgument;
28 using absl::base_internal::ThrowStdDomainError;
29 using absl::base_internal::ThrowStdLengthError;
30 using absl::base_internal::ThrowStdOutOfRange;
31 using absl::base_internal::ThrowStdRuntimeError;
32 using absl::base_internal::ThrowStdRangeError;
33 using absl::base_internal::ThrowStdOverflowError;
34 using absl::base_internal::ThrowStdUnderflowError;
35 using absl::base_internal::ThrowStdBadFunctionCall;
36 using absl::base_internal::ThrowStdBadAlloc;
37 
38 constexpr const char* what_arg = "The quick brown fox jumps over the lazy dog";
39 
40 template <typename E>
ExpectThrowChar(void (* f)(const char *))41 void ExpectThrowChar(void (*f)(const char*)) {
42 #ifdef ABSL_HAVE_EXCEPTIONS
43   try {
44     f(what_arg);
45     FAIL() << "Didn't throw";
46   } catch (const E& e) {
47     EXPECT_STREQ(e.what(), what_arg);
48   }
49 #else
50   EXPECT_DEATH_IF_SUPPORTED(f(what_arg), what_arg);
51 #endif
52 }
53 
54 template <typename E>
ExpectThrowString(void (* f)(const std::string &))55 void ExpectThrowString(void (*f)(const std::string&)) {
56 #ifdef ABSL_HAVE_EXCEPTIONS
57   try {
58     f(what_arg);
59     FAIL() << "Didn't throw";
60   } catch (const E& e) {
61     EXPECT_STREQ(e.what(), what_arg);
62   }
63 #else
64   EXPECT_DEATH_IF_SUPPORTED(f(what_arg), what_arg);
65 #endif
66 }
67 
68 template <typename E>
ExpectThrowNoWhat(void (* f)())69 void ExpectThrowNoWhat(void (*f)()) {
70 #ifdef ABSL_HAVE_EXCEPTIONS
71   try {
72     f();
73     FAIL() << "Didn't throw";
74   } catch (const E& e) {
75   }
76 #else
77   EXPECT_DEATH_IF_SUPPORTED(f(), "");
78 #endif
79 }
80 
TEST(ThrowHelper,Test)81 TEST(ThrowHelper, Test) {
82   // Not using EXPECT_THROW because we want to check the .what() message too.
83   ExpectThrowChar<std::logic_error>(ThrowStdLogicError);
84   ExpectThrowChar<std::invalid_argument>(ThrowStdInvalidArgument);
85   ExpectThrowChar<std::domain_error>(ThrowStdDomainError);
86   ExpectThrowChar<std::length_error>(ThrowStdLengthError);
87   ExpectThrowChar<std::out_of_range>(ThrowStdOutOfRange);
88   ExpectThrowChar<std::runtime_error>(ThrowStdRuntimeError);
89   ExpectThrowChar<std::range_error>(ThrowStdRangeError);
90   ExpectThrowChar<std::overflow_error>(ThrowStdOverflowError);
91   ExpectThrowChar<std::underflow_error>(ThrowStdUnderflowError);
92 
93   ExpectThrowString<std::logic_error>(ThrowStdLogicError);
94   ExpectThrowString<std::invalid_argument>(ThrowStdInvalidArgument);
95   ExpectThrowString<std::domain_error>(ThrowStdDomainError);
96   ExpectThrowString<std::length_error>(ThrowStdLengthError);
97   ExpectThrowString<std::out_of_range>(ThrowStdOutOfRange);
98   ExpectThrowString<std::runtime_error>(ThrowStdRuntimeError);
99   ExpectThrowString<std::range_error>(ThrowStdRangeError);
100   ExpectThrowString<std::overflow_error>(ThrowStdOverflowError);
101   ExpectThrowString<std::underflow_error>(ThrowStdUnderflowError);
102 
103   ExpectThrowNoWhat<std::bad_function_call>(ThrowStdBadFunctionCall);
104   ExpectThrowNoWhat<std::bad_alloc>(ThrowStdBadAlloc);
105 }
106 
107 }  // namespace
108