| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- //
- // either_stream.t.h
- // optional.stream
- //
- // Created by Sam Jaffe on 1/30/17.
- //
- #include <gmock/gmock.h>
- #include <cmath>
- #include "stream/either_stream.hpp"
- enum class MathError {
- OutOfBounds,
- DivideByZero,
- DomainError
- };
- using MathObject = either<double, MathError>;
- MathObject divide(double num, double den) {
- if (std::abs(den) < 0.000000001) {
- return MathError::DivideByZero;
- } else {
- return num / den;
- }
- }
- double multiply(double lhs, double rhs) { return lhs * rhs; }
- MathObject log(double value, double base) {
- if (value <= 0) {
- return MathError::DomainError;
- } else {
- return divide(std::log(value), std::log(base));
- }
- }
- using ::testing::DoubleNear;
- using ::testing::Eq;
- TEST(EitherStreamTest, ContainsErrorValue) {
- auto strm = stream::either::make_stream<MathObject>(1.0)
- .flatmap([](double d) { return divide(d, 0); });
-
- EXPECT_THAT(strm.value().index(), Eq(1));
- EXPECT_THAT(std::get<MathError>(strm.value()), Eq(MathError::DivideByZero));
- }
- TEST(EitherStreamTest, ErrorValueMatchesToErrorHandler) {
- auto bad_value = [](double) { throw std::logic_error("Expected error"); };
- auto strm = stream::either::make_stream<MathObject>(1.0)
- .flatmap([](double d) { return divide(d, 0); });
-
- EXPECT_NO_THROW(strm.match(bad_value, [](MathError e) {}));
- }
- TEST(EitherStreamTest, ConcreteValueMatchesToConreteHandler) {
- auto bad_error = [](MathError) { throw std::logic_error("Expected value"); };
- auto strm = stream::either::make_stream<MathObject>(1.0)
- .map([](double d) { return multiply(d, 10.0); });
-
- EXPECT_NO_THROW(strm.match([](double d) {}, bad_error));
- }
- TEST(EitherStreamTest, ErrorPropogatesBypassingMap) {
- auto bad_value = [](double) { throw std::logic_error("Expected error"); };
- auto strm = stream::either::make_stream<MathObject>(1.0)
- .flatmap([](double d) { return divide(d, 0); });
-
- EXPECT_NO_THROW(strm = strm.map([](double) {
- throw std::runtime_error("Mapping while invalid");
- return 0.0;
- }));
- EXPECT_NO_THROW(strm.match(bad_value, [](MathError e) {}));
- }
- TEST(EitherStreamTest, ErrorPropogatesBypassingFlatmap) {
- auto ex = stream::either::make_stream<MathObject>(1.0)
- .flatmap([](double d) { return log(0.0, d); });
- EXPECT_THAT(std::get<MathError>(ex.value()), Eq(MathError::DomainError));
- auto strm = stream::either::make_stream<MathObject>(1.0)
- .flatmap([](double d) { return log(1.0, d); });
- EXPECT_THAT(std::get<MathError>(strm.value()), Eq(MathError::DivideByZero));
-
- strm = strm.flatmap([](double d) { return log(0.0, d); });
- EXPECT_THAT(std::get<MathError>(strm.value()), Eq(MathError::DivideByZero));
- }
|