kaycxx-test
C++ unit test framework
Loading...
Searching...
No Matches
assert_throw.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Klaus Reimer <k@ailis.de>
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
11#include <concepts>
12#include <exception>
13#include <format>
14#include <functional>
15#include <optional>
16#include <regex>
17#include <source_location>
18#include <string_view>
19#include <utility>
20
22#include <kaycxx/test/detail/exception_type.hpp>
23#include <kaycxx/test/detail/exception_type_name.hpp>
24#include <kaycxx/test/detail/to_string.hpp>
25
26namespace kaycxx::test {
27
44template <detail::exception_type Exception, std::invocable Function>
46 Function&& function,
47 std::string_view expected_message,
48 std::string_view reason = {},
49 std::optional<std::source_location> location = std::source_location::current()
50) {
51 auto expected_type = detail::exception_type_name<Exception>();
52
53 try {
54 std::invoke(std::forward<Function>(function));
55 } catch (Exception const& exception) {
56 auto actual_message = std::string_view(exception.what());
57 if (actual_message == expected_message) {
58 return;
59 }
60
61 auto actual_string = detail::to_string(actual_message);
62 auto expected_string = detail::to_string(expected_message);
63 auto message = std::format(
64 "Expected exception message <{}> but caught <{}>",
65 expected_string,
66 actual_string
67 );
68 throw assertion_error(message, reason, std::move(actual_string), std::move(expected_string), location);
69 } catch (std::exception const& exception) {
70 auto actual_string = detail::exception_type_name(exception);
71 auto message = std::format(
72 "Expected function to throw exception of type <{}> but caught <{}>",
73 expected_type,
74 actual_string
75 );
76 throw assertion_error(message, reason, std::move(actual_string), std::move(expected_type), location);
77 } catch (...) {
78 auto message = std::format(
79 "Expected function to throw exception of type <{}> but caught <unknown exception>",
80 expected_type
81 );
82 throw assertion_error(message, reason, "unknown exception", std::move(expected_type), location);
83 }
84
85 auto expected_string = detail::to_string(expected_message);
86 auto message = std::format(
87 "Expected function to throw exception of type <{}> with message <{}>",
88 expected_type,
89 expected_string
90 );
91 throw assertion_error(message, reason, "no exception", std::move(expected_string), location);
92}
93
110template <detail::exception_type Exception, std::invocable Function>
112 Function&& function,
113 std::regex const& expected_message,
114 std::string_view reason = {},
115 std::optional<std::source_location> location = std::source_location::current()
116) {
117 auto expected_type = detail::exception_type_name<Exception>();
118
119 try {
120 std::invoke(std::forward<Function>(function));
121 } catch (Exception const& exception) {
122 auto actual_message = std::string_view(exception.what());
123 if (std::regex_match(actual_message.begin(), actual_message.end(), expected_message)) {
124 return;
125 }
126
127 auto actual_string = detail::to_string(actual_message);
128 auto message = std::format("Expected exception message to match regex but caught <{}>", actual_string);
129 throw assertion_error(message, reason, std::move(actual_string), "regex", location);
130 } catch (std::exception const& exception) {
131 auto actual_string = detail::exception_type_name(exception);
132 auto message = std::format(
133 "Expected function to throw exception of type <{}> but caught <{}>",
134 expected_type,
135 actual_string
136 );
137 throw assertion_error(message, reason, std::move(actual_string), std::move(expected_type), location);
138 } catch (...) {
139 auto message = std::format(
140 "Expected function to throw exception of type <{}> but caught <unknown exception>",
141 expected_type
142 );
143 throw assertion_error(message, reason, "unknown exception", std::move(expected_type), location);
144 }
145
146 auto message = std::format(
147 "Expected function to throw exception of type <{}> with message matching regex",
148 expected_type
149 );
150 throw assertion_error(message, reason, "no exception", "regex", location);
151}
152
153} // namespace kaycxx::test
Defines the assertion_error type.
Unit test framework functions and types.
Definition test.hpp:15
void assert_throw(Function &&function, std::string_view expected_message, std::string_view reason={}, std::optional< std::source_location > location=std::source_location::current())
Asserts that the function throws an exception of the expected type with the exact expected message.
Definition assert_throw.hpp:45