C++Spec 1.0.0
BDD testing for C++
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1
2#pragma once
3
4#include <version>
5#include <format>
6#include <source_location>
7#include <sstream>
8#include <string>
9#include <utility>
10
11namespace CppSpec {
12
13class Result {
14 public:
15 enum class Status { Success, Failure, Error, Skipped };
16
17 Result() = default;
18
19 /*--------- Status helper functions --------------*/
20 void set_status(Status status) noexcept { status_ = status; }
21 [[nodiscard]] Status status() const noexcept { return status_; }
22 [[nodiscard]] bool is_success() const noexcept { return status_ == Status::Success; }
23 [[nodiscard]] bool is_failure() const noexcept { return status_ == Status::Failure; }
24 [[nodiscard]] bool skipped() const noexcept { return status_ == Status::Skipped; }
25 [[nodiscard]] bool is_error() const noexcept { return status_ == Status::Error; }
26
27 static Result reduce(const Result& lhs, const Result& rhs) noexcept {
28 if (lhs.is_failure()) return lhs;
29 if (rhs.is_failure()) return rhs;
30 if (lhs.is_error()) return lhs;
31 if (rhs.is_error()) return rhs;
32 if (lhs.is_success()) return lhs;
33 if (rhs.is_success()) return rhs;
34 return lhs;
35 }
36
37 /*--------- Location helper functions ------------*/
38 [[nodiscard]] std::source_location get_location() const noexcept { return location; }
39 [[nodiscard]] std::string get_location_string() const noexcept {
40 return std::format("{}:{}:{}", location.file_name(), location.line(), location.column());
41 }
42
43 [[nodiscard]] std::string get_type() const noexcept { return type; }
44 void set_type(std::string type) noexcept { this->type = std::move(type); }
45
46 /*--------- Message helper functions -------------*/
47 [[nodiscard]] std::string get_message() const noexcept { return message; }
48 Result& set_message(std::string message) noexcept {
49 this->message = std::move(message);
50 return *this;
51 }
52
53 /*--------- Explicit constructor functions -------*/
54 static Result success(std::source_location location) noexcept { return {Status::Success, location}; }
55 static Result failure(std::source_location location) noexcept { return {Status::Failure, location}; }
56 static Result success_with(std::source_location location, std::string success_message) noexcept {
57 return {Status::Success, location, std::move(success_message)};
58 }
59 static Result failure_with(std::source_location location, std::string failure_message) noexcept {
60 return {Status::Failure, location, std::move(failure_message)};
61 }
62
63 static Result error(std::source_location location) noexcept { return {Status::Error, location}; }
64 static Result error_with(std::source_location location, std::string error_message) noexcept {
65 return {Status::Error, location, std::move(error_message)};
66 }
67
68 static Result skipped(std::source_location location) noexcept { return {Status::Skipped, location}; }
69 static Result skipped_with(std::source_location location, std::string skipped_message) noexcept {
70 return {Status::Skipped, location, std::move(skipped_message)};
71 }
72
73 /*-------------- Friend functions ----------------*/
74
75 // Stream operator
76 friend std::ostream& operator<<(std::ostream& os, const Result& res) {
77 std::stringstream ss;
78 switch (res.status()) {
79 case Status::Success:
80 ss << "Success";
81 break;
82 case Status::Failure:
83 ss << "Failure";
84 break;
85 case Status::Error:
86 ss << "Error";
87 break;
88 case Status::Skipped:
89 ss << "Skipped";
90 break;
91 }
92
93 if (not res.get_message().empty()) {
94 ss << "(\"" + res.get_message() + "\")";
95 }
96
97 return os << ss.str();
98 }
99
100 private:
101 Status status_ = Status::Success;
102 std::source_location location;
103 std::string message;
104 std::string type;
105 Result(Status status, std::source_location location, std::string message = "") noexcept
106 : status_(status), location(location), message(std::move(message)) {}
107};
108
109template <typename T>
110constexpr bool is_result_v = std::is_same_v<Result, T>;
111
112template <typename T>
113concept is_result = is_result_v<T>;
114
115} // namespace CppSpec
Definition result.hpp:113