aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/testing/gtest_extensions/assertions.cpp
blob: f390409d1b3dbcd36cc6110f931c33c97e4f9446 (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
#include "assertions.h"

#include <util/string/builder.h>
#include <util/string/split.h>
#include <util/system/type_name.h>

namespace NGTest::NInternal {
    namespace {
        void FormatActual(const std::exception& err, const TBackTrace* bt, TStringBuilder& out) {
            out << "an exception of type " << TypeName(err) << " "
                << "with message " << TString(err.what()).Quote() << ".";
            if (bt) {
                out << "\n   Trace: ";
                for (auto& line: StringSplitter(bt->PrintToString()).Split('\n')) {
                    out << "          " << line.Token() << "\n";
                }
            }
        }

        void FormatActual(TStringBuilder& out) {
            out << "  Actual: it throws ";
            auto exceptionPtr = std::current_exception();
            if (exceptionPtr) {
                try {
                    std::rethrow_exception(exceptionPtr);
                } catch (const yexception& err) {
                    FormatActual(err, err.BackTrace(), out);
                    return;
                } catch (const std::exception& err) {
                    FormatActual(err, nullptr, out);
                    return;
                } catch (...) {
                    out << "an unknown exception.";
                    return;
                }
            }
            out << "nothing.";
        }

        void FormatExpected(const char* statement, const char* type, const TString& contains, TStringBuilder& out) {
            out << "Expected: ";
            if (TStringBuf(statement).size() > 80) {
                out << "statement";
            } else {
                out << statement;
            }
            out << " throws an exception of type " << type;

            if (!contains.empty()) {
                out << " with message containing " << contains.Quote();
            }

            out << ".";
        }
    }

    TString FormatErrorWrongException(const char* statement, const char* type) {
        return FormatErrorWrongException(statement, type, "");
    }

    TString FormatErrorWrongException(const char* statement, const char* type, TString contains) {
        TStringBuilder out;

        FormatExpected(statement, type, contains, out);
        out << "\n";
        FormatActual(out);

        return out;
    }

    TString FormatErrorUnexpectedException(const char* statement) {
        TStringBuilder out;

        out << "Expected: ";
        if (TStringBuf(statement).size() > 80) {
            out << "statement";
        } else {
            out << statement;
        }
        out << " doesn't throw an exception.\n  ";

        FormatActual(out);

        return out;
    }

    bool ExceptionMessageContains(const std::exception& err, TString contains) {
        return TStringBuf(err.what()).Contains(contains);
    }
}