1 /* Copyright 2017-2018 Fizyr B.V. - https://fizyr.com
2 *
3 * Redistribution and use in source and binary forms, with or without modification,
4 * are permitted provided that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain the above copyright notice,
7 * this list of conditions and the following disclaimer.
8 *
9 * 2. Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 *
13 * 3. Neither the name of the copyright holder nor the names of its contributors
14 * may be used to endorse or promote products derived from this software without
15 * specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "result/error.hpp"
30 #include "traits/is_comparible.hpp"
31 #include "result/catch_string_conversions.hpp"
32
33 #include <catch2/catch.hpp>
34
35 namespace estd {
36
37 class test_category_ : public std::error_category {
name() const38 char const * name() const noexcept override {
39 return "test";
40 }
41
message(int code) const42 std::string message(int code) const override {
43 switch (code) {
44 case 1: return "one";
45 case 2: return "two";
46 case 3: return "three";
47 }
48 return "unknown error";
49 }
50 } test_category_;
51
test_category()52 std::error_category const & test_category() {
53 return test_category_;
54 }
55
56
57 TEST_CASE("error compares to std::error_code", "[result]") {
58 static_assert(is_comparible<error, std::error_code>);
59 REQUIRE(error{std::errc::invalid_argument} == make_error_code(std::errc::invalid_argument));
60 REQUIRE(error{std::errc::invalid_argument} != make_error_code(std::errc::address_in_use));
61 }
62
63 TEST_CASE("error compares to std::error_condition", "[result]") {
64 static_assert(is_comparible<error, std::errc>);
65 REQUIRE(error{std::errc::invalid_argument} == make_error_condition(std::errc::invalid_argument));
66 REQUIRE(error{std::errc::invalid_argument} != make_error_condition(std::errc::address_in_use));
67 }
68
69 TEST_CASE("error compares to std::errc", "[result]") {
70 static_assert(is_comparible<error, std::error_condition>);
71 REQUIRE(error{std::errc::invalid_argument} == std::errc::invalid_argument);
72 REQUIRE(error{std::errc::invalid_argument} != std::errc::address_in_use);
73 }
74
75 TEST_CASE("error is not comparible with itself", "[result]") {
76 static_assert(is_comparible<error, error> == false);
77 CHECK((is_comparible<error, error>) == false);
78 }
79
80 TEST_CASE("unspecified errors have the right category and value", "[result]") {
81 CHECK(error("aap").code == unspecified_errc::unspecified);
82 CHECK(error({"aap", "noot"}).code == unspecified_errc::unspecified);
83 }
84
85 TEST_CASE("error.format_code() formats correctly", "[result]") {
86 std::error_code test_code = {1, test_category()};
87
88 CHECK(error(test_code).format_code() == "test error 1: one");
89 SECTION("error description does not influence format_code()") {
90 CHECK(error(test_code, "aap").format_code() == "test error 1: one");
91 }
92
93 SECTION("errors of unspecified category only print the category name and value") {
94 CHECK(error(unspecified_errc::unspecified).format_code() == "unspecified error -1");
95 CHECK(error({1, unspecified_error_category()}).format_code() == "unspecified error 1");
96 }
97 }
98
99 TEST_CASE("error.format_description() formats correctly", "[result]") {
100 CHECK(error(std::errc::invalid_argument).format_description() == "");
101 CHECK(error(std::errc::invalid_argument, "aap").format_description() == "aap");
102 CHECK(error(std::errc::invalid_argument, {"aap", "noot"}).format_description() == "noot: aap");
103 }
104
105 TEST_CASE("error.format() formats correctly", "[result]") {
106 std::error_code test_code = {1, test_category()};
107
108 CHECK(error(test_code).format() == "test error 1: one");
109 CHECK(error(test_code, "aap").format() == "aap: test error 1: one");
110 CHECK(error(test_code, {"aap", "noot"}).format() == "noot: aap: test error 1: one");
111
112 SECTION("unspecified errors don't include the code") {
113 CHECK(error("aap").format() == "aap");
114 CHECK(error({"aap", "noot"}).format() == "noot: aap");
115 SECTION("unless they have no description") {
116 CHECK(error(unspecified_errc::unspecified).format() == "unspecified error -1");
117 }
118 }
119 }
120
121 }
122