71 TEST_CASE(
"expected construction") {
74 SUBCASE(
"when T is a integral type, it should be constructible") {
75 expected<int, std::string> e(42);
77 CHECK_EQ(e.value(), 42);
81 SUBCASE(
"when T is a string, it should be constructible") {
82 expected<std::string, int> e(
"success");
84 CHECK_EQ(e.value(),
"success");
88 SUBCASE(
"when T and E are the same type, it should be constructible") {
89 expected<std::string, std::string> e(
"success");
91 CHECK_EQ(e.value(),
"success");
95 SUBCASE(
"when T is a custom type, it should be constructible") {
96 expected<CustomValue, std::string> e(CustomValue{200,
"OK"});
98 CHECK_EQ(e.value().code, 200);
99 CHECK_EQ(e.value().message,
"OK");
100 CHECK(e.has_value());
104 TEST_CASE(
"arrow operator") {
106 "when T is a class with member functions, arrow operator should work") {
108 expected<Sample, std::string> e;
110 CHECK_EQ(e->value(), 42);
120 TEST_CASE(
"asterisk operator") {
121 SUBCASE(
"when T is a class with member functions, * operator should work") {
122 expected<int, std::string> e(42);
128 TEST_CASE(
"bool operator") {
129 SUBCASE(
"when has_value is true, bool operator should return true") {
130 expected<int, std::string> e(42);
134 SUBCASE(
"when has_value is false, bool operator should return false") {
135 expected<int, std::string> e(unexpected<std::string>(
"error"));
140 TEST_CASE(
"has_value") {
141 SUBCASE(
"has_value should return true when value is present") {
142 expected<int, std::string> e(42);
143 CHECK(e.has_value());
146 SUBCASE(
"has_value should return false when error is present") {
147 expected<int, std::string> e(unexpected<std::string>(
"error"));
148 CHECK(!e.has_value());
153 SUBCASE(
"value should return the value when has_value is true") {
154 expected<int, std::string> e(42);
155 CHECK_EQ(e.value(), 42);
158 SUBCASE(
"value should throw when has_value is false") {
159 expected<int, std::string> e(unexpected<std::string>(
"error"));
160 CHECK_THROWS_AS(e.value(), bad_expected_access);
165 SUBCASE(
"error should return the error when has_value is false") {
166 expected<int, std::string> e(unexpected<std::string>(
"error"));
167 CHECK_EQ(e.error(),
"error");
170 SUBCASE(
"error should throw when has_value is true") {
171 expected<int, std::string> e(42);
172 CHECK_THROWS_AS(e.error(), bad_expected_access);
176 TEST_CASE(
"value_or") {
177 SUBCASE(
"value_or should return the value when has_value is true") {
178 expected<int, std::string> e(42);
179 CHECK_EQ(e.value_or(0), 42);
183 "value_or should return the default value when has_value is false") {
184 expected<int, std::string> e(unexpected<std::string>(
"error"));
185 CHECK_EQ(e.value_or(0), 0);
189 TEST_CASE(
"error_or") {
190 SUBCASE(
"error_or should return the error when has_value is false") {
191 expected<int, std::string> e(unexpected<std::string>(
"error"));
192 CHECK_EQ(e.error_or(
"default error"),
"error");
195 SUBCASE(
"error_or should return the default value when has_value is true") {
196 expected<int, std::string> e(42);
197 CHECK_EQ(e.error_or(
"default error"),
"default error");
201 TEST_CASE(
"and_then") {
202 SUBCASE(
"and_then should call the function when has_value is true") {
203 const auto div2 = [](
int value) -> expected<int, std::string> {
204 return expected<int, std::string>(value / 2);
208 const expected<int, std::string> e1(42);
209 const auto result = e1.and_then(div2);
211 CHECK(result.has_value());
212 CHECK_EQ(result.value(), 21);
215 const expected<int, std::string> e2(44);
216 const auto result2 = e2.and_then(div2).and_then(div2);
218 CHECK(result2.has_value());
219 CHECK_EQ(result2.value(), 11);
222 SUBCASE(
"and_then should not call the function when has_value is false") {
223 const auto div2 = [](
int value) -> expected<int, std::string> {
224 return expected<int, std::string>(value / 2);
228 const expected<int, std::string> e1(unexpected<std::string>(
"error"));
229 const auto result1 = e1.and_then(div2);
231 CHECK(!result1.has_value());
232 CHECK_EQ(result1.error(),
"error");
235 const expected<int, std::string> e2(unexpected<std::string>(
"error"));
236 const auto result2 = e2.and_then(div2).and_then(div2);
238 CHECK(!result2.has_value());
239 CHECK_EQ(result2.error(),
"error");
242 SUBCASE(
"and_then with member function should work") {
243 const auto get_value = [](
const Sample& s) {
244 return expected<int, std::string>(s.value());
248 expected<Sample, std::string> e(Sample{});
249 const auto result = e.and_then(get_value);
251 CHECK(result.has_value());
252 CHECK_EQ(result.value(), 42);
256 const expected<int, std::string> e1(42);
259 const auto res1 = e1.and_then(FizzBuzz);
260 const auto res2 = e1.and_then(FizzBuzzRef);
262 CHECK(res1.has_value());
263 CHECK_EQ(res1.value(),
"Fizz");
264 CHECK(res2.has_value());
265 CHECK_EQ(res2.value(),
"Fizz");