Hegel 0.11.4
Property-based testing for C++
Loading...
Searching...
No Matches
gtest.h
1#pragma once
2
29
30#include <gtest/gtest-spi.h>
31#include <gtest/gtest.h>
32
33#include "hegel.h"
34
35#include <functional>
36#include <stdexcept>
37#include <string>
38
39namespace hegel {
40
51 class GTestFailure : public std::runtime_error, public FailureOrigin {
52 public:
55 GTestFailure(std::string origin, const std::string& message)
56 : std::runtime_error(message), origin_(std::move(origin)) {}
57
59 std::string failure_origin() const override { return origin_; }
60
61 private:
62 std::string origin_;
63 };
64
66 namespace internal {
67 namespace gtest_hooks {
68
69 // "Suite.Name" of the GoogleTest test that runs now.
70 inline std::string current_test_name() {
71 const testing::TestInfo* info =
72 testing::UnitTest::GetInstance()->current_test_info();
73 if (info == nullptr) {
74 return {};
75 }
76 return std::string(info->test_suite_name()) + "." +
77 info->name();
78 }
79
80 // Where one failed assertion is written, or "<unknown>" for an
81 // assertion GoogleTest could not place.
82 inline std::string position(const testing::TestPartResult& part) {
83 if (part.file_name() == nullptr) {
84 return "<unknown>";
85 }
86 return std::string(part.file_name()) + ":" +
87 std::to_string(part.line_number());
88 }
89
90 struct Failures {
91 std::string message;
92 std::string origin;
93 };
94
95 inline Failures
96 collect_failures(const testing::TestPartResultArray& recorded) {
97 Failures out;
98 for (int i = 0; i < recorded.size(); i++) {
99 const testing::TestPartResult& part =
100 recorded.GetTestPartResult(i);
101 if (!part.failed()) {
102 continue;
103 }
104 if (!out.message.empty()) {
105 out.message += "\n";
106 out.origin += ", ";
107 }
108 out.message += position(part) + ": " + part.message();
109 out.origin += position(part);
110 }
111 return out;
112 }
113
114 // Runs one test-case body and collects GoogleTest assertions, then
115 // raises them as one exception.
116 inline void run_case(const std::function<void()>& body) {
117 if (testing::UnitTest::GetInstance()->current_test_info() ==
118 nullptr) {
119 body();
120 return;
121 }
122 testing::TestPartResultArray recorded;
123 {
124 testing::ScopedFakeTestPartResultReporter reporter(
125 testing::ScopedFakeTestPartResultReporter::
126 INTERCEPT_ONLY_CURRENT_THREAD,
127 &recorded);
128 body();
129 }
130 Failures failures = collect_failures(recorded);
131 if (!failures.message.empty()) {
132 throw GTestFailure("hegel::GTestFailure at " +
133 failures.origin,
134 failures.message);
135 }
136 }
137
138 } // namespace gtest_hooks
139
140 [[maybe_unused]] static const bool hegel_gtest_hooks_installed =
141 install_framework_hooks(
142 {&gtest_hooks::current_test_name, &gtest_hooks::run_case});
143 } // namespace internal
145
146} // namespace hegel
GTestFailure(std::string origin, const std::string &message)
Definition gtest.h:55
std::string failure_origin() const override
Definition gtest.h:59
Main namespace.
Definition config.h:29