aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/testing/gtest_extensions/assertions.h
blob: 9532b5ed96b9598c5fea0d46f17691bea6fb6210 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#pragma once 
 
#include <util/generic/string.h> 
 
#include <gtest/gtest.h>
#include <gmock/gmock.h>
 
/** 
 * Check that the given statement throws an exception of the given type, 
 * and that the thrown exception message contains the given substring. 
 */ 
#define EXPECT_THROW_MESSAGE_HAS_SUBSTR(statement, expectedException, substring) \ 
    _Y_GTEST_EXPECT_THROW_MESSAGE_HAS_SUBSTR_IMPL_(statement, expectedException, substring, GTEST_NONFATAL_FAILURE_) 
 
/** 
 * Check that the given statement throws an exception of the given type, 
 * and that the thrown exception message contains the given substring. 
 */ 
#define ASSERT_THROW_MESSAGE_HAS_SUBSTR(statement, expectedException, substring) \ 
    _Y_GTEST_EXPECT_THROW_MESSAGE_HAS_SUBSTR_IMPL_(statement, expectedException, substring, GTEST_FATAL_FAILURE_) 
 
 
// Improve default macros. New implementation shows better exception messages. 
// See https://github.com/google/googletest/issues/2878 
 
#undef EXPECT_THROW 
#define EXPECT_THROW(statement, expectedException) \ 
    _Y_GTEST_EXPECT_THROW_IMPL_(statement, expectedException, GTEST_NONFATAL_FAILURE_) 
 
#undef ASSERT_THROW 
#define ASSERT_THROW(statement, expectedException) \ 
    _Y_GTEST_EXPECT_THROW_IMPL_(statement, expectedException, GTEST_FATAL_FAILURE_) 
 
#undef EXPECT_NO_THROW 
#define EXPECT_NO_THROW(statement) \ 
    _Y_GTEST_EXPECT_NO_THROW_IMPL_(statement, GTEST_NONFATAL_FAILURE_) 
 
#undef ASSERT_NO_THROW 
#define ASSERT_NO_THROW(statement) \ 
    _Y_GTEST_EXPECT_NO_THROW_IMPL_(statement, GTEST_FATAL_FAILURE_) 
 
 
// Implementation details 
 
namespace NGTest::NInternal { 
    TString FormatErrorWrongException(const char* statement, const char* type); 
    TString FormatErrorWrongException(const char* statement, const char* type, TString contains); 
    TString FormatErrorUnexpectedException(const char* statement); 
    bool ExceptionMessageContains(const std::exception& err, TString contains); 
} 
 
#define _Y_GTEST_EXPECT_THROW_IMPL_(statement, expectedException, fail)                                             \ 
    GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                                                   \ 
    if (::TString gtestMsg = ""; ::testing::internal::AlwaysTrue()) {                                               \ 
        bool gtestCaughtExpected = false;                                                                           \ 
        try {                                                                                                       \ 
            GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);                                              \ 
        } catch (expectedException const&) {                                                                        \ 
            gtestCaughtExpected = true;                                                                             \ 
        } catch (...) {                                                                                             \ 
            gtestMsg = ::NGTest::NInternal::FormatErrorWrongException(                                              \ 
                #statement, #expectedException);                                                                    \ 
            goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);                                             \ 
        } if (!gtestCaughtExpected) {                                                                               \ 
            gtestMsg = ::NGTest::NInternal::FormatErrorWrongException(                                              \ 
                #statement, #expectedException);                                                                    \ 
            goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);                                             \ 
        }                                                                                                           \ 
    } else                                                                                                          \ 
        GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__):                                                      \ 
            fail(gtestMsg.c_str()) 
 
#define _Y_GTEST_EXPECT_THROW_MESSAGE_HAS_SUBSTR_IMPL_(statement, expectedException, substring, fail)               \ 
    GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                                                   \ 
    if (::TString gtestMsg = ""; ::testing::internal::AlwaysTrue()) {                                               \ 
        bool gtestCaughtExpected = false;                                                                           \ 
        ::TString gtestSubstring{substring};                                                                        \ 
        try {                                                                                                       \ 
            GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);                                              \ 
        } catch (expectedException const& gtestError) {                                                             \ 
            if (!::NGTest::NInternal::ExceptionMessageContains(gtestError, gtestSubstring)) {                       \ 
                gtestMsg = ::NGTest::NInternal::FormatErrorWrongException(                                          \ 
                    #statement, #expectedException, gtestSubstring);                                                \ 
                goto GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__);                                   \ 
            }                                                                                                       \ 
            gtestCaughtExpected = true;                                                                             \ 
        } catch (...) {                                                                                             \ 
            gtestMsg = ::NGTest::NInternal::FormatErrorWrongException(                                              \ 
                #statement, #expectedException, gtestSubstring);                                                    \ 
            goto GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__);                                       \ 
        } if (!gtestCaughtExpected) {                                                                               \ 
            gtestMsg = ::NGTest::NInternal::FormatErrorWrongException(                                              \ 
                #statement, #expectedException, gtestSubstring);                                                    \ 
            goto GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__);                                       \ 
        }                                                                                                           \ 
    } else                                                                                                          \ 
        GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__):                                                \ 
            fail(gtestMsg.c_str()) 
 
#define _Y_GTEST_EXPECT_NO_THROW_IMPL_(statement, fail)                                                             \ 
    GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                                                   \ 
    if (::TString gtestMsg = ""; ::testing::internal::AlwaysTrue()) {                                               \ 
        try {                                                                                                       \ 
            GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);                                              \ 
        } catch (...) {                                                                                             \ 
            gtestMsg = ::NGTest::NInternal::FormatErrorUnexpectedException(#statement);                             \ 
            goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__);                                           \ 
        }                                                                                                           \ 
    } else                                                                                                          \ 
        GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__):                                                    \ 
            fail(gtestMsg.c_str())