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