Skip to content

Commit 01f848e

Browse files
authored
Merge pull request #245 from eseiler/misc/expect_thow_msg
[TEST] Add EXPECT_THROW_MSG
2 parents 64399ce + 3295fa5 commit 01f848e

File tree

4 files changed

+87
-64
lines changed

4 files changed

+87
-64
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-FileCopyrightText: 2006-2024, Knut Reinert & Freie Universität Berlin
2+
// SPDX-FileCopyrightText: 2016-2024, Knut Reinert & MPI für molekulare Genetik
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
/*!\file
6+
* \brief Provides EXPECT_THROW_MSG.
7+
* \author Enrico Seiler <enrico.seiler AT fu-berlin.de>
8+
*/
9+
10+
#pragma once
11+
12+
#include <gtest/gtest.h>
13+
14+
#ifdef EXPECT_THROW_MSG
15+
# warning "EXPECT_THROW_MSG is already defined."
16+
#else
17+
# define EXPECT_THROW_MSG(statement, expected_exception, expected_message) \
18+
try \
19+
{ \
20+
statement; \
21+
std::string const message = "Expected: " #statement " throws an exception of type " #expected_exception \
22+
".\n Actual: it throws nothing."; \
23+
GTEST_NONFATAL_FAILURE_(message.data()); \
24+
} \
25+
catch (expected_exception const & exception) \
26+
{ \
27+
if (auto result = ::testing::internal::EqHelper::Compare("Expected", \
28+
"Actual", \
29+
std::string_view{expected_message}, \
30+
std::string_view{exception.what()}); \
31+
!result) \
32+
{ \
33+
std::string message = #statement " throws the correct exception, but the description is incorrect.\n"; \
34+
message += result.failure_message(); \
35+
GTEST_NONFATAL_FAILURE_(message.data()); \
36+
} \
37+
} \
38+
catch (std::exception const & exception) \
39+
{ \
40+
std::string message = "Expected: " #statement " throws an exception of type " #expected_exception ".\n "; \
41+
message += "Actual: it throws "; \
42+
message += ::testing::internal::GetTypeName(typeid(exception)); \
43+
message += " with description \""; \
44+
message += exception.what(); \
45+
message += "\"."; \
46+
GTEST_NONFATAL_FAILURE_(message.data()); \
47+
} \
48+
catch (...) \
49+
{ \
50+
std::string message = "Expected: " #statement " throws an exception of type " #expected_exception ".\n "; \
51+
message += "Actual: it throws an unknown exception."; \
52+
GTEST_NONFATAL_FAILURE_(message.data()); \
53+
}
54+
#endif

test/unit/parser/enumeration_names_test.cpp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <ranges>
88

99
#include <sharg/parser.hpp>
10+
#include <sharg/test/expect_throw_msg.hpp>
1011
#include <sharg/test/test_fixture.hpp>
1112

1213
namespace foo
@@ -112,34 +113,19 @@ TEST_F(enumeration_names_test, enum_error_message)
112113
foo::bar value{};
113114
Other::bar value2{};
114115

115-
auto parser = get_parser();
116-
117-
auto check_error = [&parser](std::string_view const expected)
118-
{
119-
try
120-
{
121-
parser.parse();
122-
FAIL();
123-
}
124-
catch (sharg::user_input_error const & exception)
125-
{
126-
EXPECT_EQ(expected, exception.what());
127-
}
128-
catch (...)
129-
{
130-
FAIL();
131-
}
132-
};
133-
134116
// foo::bar does not contain duplicate values
135-
parser = get_parser("-e", "nine");
117+
auto parser = get_parser("-e", "nine");
136118
parser.add_option(value, sharg::config{.short_id = 'e'});
137-
check_error("You have chosen an invalid input value: nine. Please use one of: [one, two, three]");
119+
EXPECT_THROW_MSG(parser.parse(),
120+
sharg::user_input_error,
121+
"You have chosen an invalid input value: nine. Please use one of: [one, two, three]");
138122

139123
// Other::bar does contain duplicate values
140124
parser = get_parser("-e", "nine");
141125
parser.add_option(value2, sharg::config{.short_id = 'e'});
142-
check_error("You have chosen an invalid input value: nine. Please use one of: [1, one, 2, two]");
126+
EXPECT_THROW_MSG(parser.parse(),
127+
sharg::user_input_error,
128+
"You have chosen an invalid input value: nine. Please use one of: [1, one, 2, two]");
143129
}
144130

145131
// https://github.com/seqan/seqan3/pull/2381

test/unit/parser/format_parse_test.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <ranges>
88

99
#include <sharg/parser.hpp>
10+
#include <sharg/test/expect_throw_msg.hpp>
1011
#include <sharg/test/test_fixture.hpp>
1112

1213
class format_parse_test : public sharg::test::test_fixture
@@ -770,22 +771,10 @@ TEST_F(format_parse_test, error_message_parsing)
770771

771772
auto parser = get_parser("--value", "-30");
772773
parser.add_option(option_value, sharg::config{.long_id = "value"});
773-
774-
try
775-
{
776-
parser.parse();
777-
FAIL();
778-
}
779-
catch (sharg::user_input_error const & exception)
780-
{
781-
std::string_view const expected_message{"Value parse failed for --value: Argument -30 could not be parsed as "
782-
"type unsigned 64 bit integer."};
783-
EXPECT_EQ(expected_message, exception.what());
784-
}
785-
catch (...)
786-
{
787-
FAIL();
788-
}
774+
EXPECT_THROW_MSG(parser.parse(),
775+
sharg::user_input_error,
776+
"Value parse failed for --value: Argument -30 could "
777+
"not be parsed as type unsigned 64 bit integer.");
789778
}
790779

791780
// https://github.com/seqan/seqan3/pull/2381

test/unit/parser/parser_design_error_test.cpp

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <gtest/gtest.h>
66

77
#include <sharg/parser.hpp>
8+
#include <sharg/test/expect_throw_msg.hpp>
89
#include <sharg/test/test_fixture.hpp>
910

1011
class design_error_test : public sharg::test::test_fixture
@@ -295,30 +296,23 @@ TEST_F(design_error_test, not_allowed_after_parse)
295296
parser.add_option(value, sharg::config{.short_id = 'i'});
296297
EXPECT_NO_THROW(parser.parse());
297298

298-
auto check_error = [](auto call_fn, std::string const function_name)
299-
{
300-
try
301-
{
302-
call_fn();
303-
FAIL();
304-
}
305-
catch (sharg::design_error const & exception)
306-
{
307-
EXPECT_EQ(function_name + " may only be used before calling parse().", exception.what());
308-
}
309-
catch (...)
310-
{
311-
FAIL();
312-
}
313-
};
314-
315-
// clang-format off
316-
check_error([&parser, &value]() { parser.add_option(value, sharg::config{.short_id = 'i'}); }, "add_option");
317-
check_error([&parser, &flag]() { parser.add_flag(flag, sharg::config{.short_id = 'i'}); }, "add_flag");
318-
check_error([&parser, &value]() { parser.add_positional_option(value, sharg::config{}); }, "add_positional_option");
319-
check_error([&parser]() { parser.add_section(""); }, "add_section");
320-
check_error([&parser]() { parser.add_subsection(""); }, "add_subsection");
321-
check_error([&parser]() { parser.add_line(""); }, "add_line");
322-
check_error([&parser]() { parser.add_list_item("", ""); }, "add_list_item");
323-
// clang-format on
299+
EXPECT_THROW_MSG(parser.add_option(value, sharg::config{.short_id = 'i'}),
300+
sharg::design_error,
301+
"add_option may only be used before calling parse().");
302+
EXPECT_THROW_MSG(parser.add_flag(flag, sharg::config{.short_id = 'i'}),
303+
sharg::design_error,
304+
"add_flag may only be used before calling parse().");
305+
EXPECT_THROW_MSG(parser.add_positional_option(value, sharg::config{}),
306+
sharg::design_error,
307+
"add_positional_option may only be used before calling parse().");
308+
EXPECT_THROW_MSG(parser.add_section(""),
309+
sharg::design_error,
310+
"add_section may only be used before calling parse().");
311+
EXPECT_THROW_MSG(parser.add_subsection(""),
312+
sharg::design_error,
313+
"add_subsection may only be used before calling parse().");
314+
EXPECT_THROW_MSG(parser.add_line(""), sharg::design_error, "add_line may only be used before calling parse().");
315+
EXPECT_THROW_MSG(parser.add_list_item("", ""),
316+
sharg::design_error,
317+
"add_list_item may only be used before calling parse().");
324318
}

0 commit comments

Comments
 (0)