| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- //
- // either_stream.t.h
- // optional.stream
- //
- // Created by Sam Jaffe on 1/30/17.
- //
- #include <cmath>
- #include <gmock/gmock.h>
- #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); });
- strm.match([](double) { GTEST_FAIL(); },
- [](MathError me) { EXPECT_THAT(me, 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); });
- ex.match([](double) { GTEST_FAIL(); },
- [](MathError me) { EXPECT_THAT(me, MathError::DomainError); });
- auto strm = stream::either::make_stream<MathObject>(1.0).flatmap(
- [](double d) { return log(1.0, d); });
- strm.match([](double) { GTEST_FAIL(); },
- [](MathError me) { EXPECT_THAT(me, MathError::DivideByZero); });
- strm = strm.flatmap([](double d) { return log(0.0, d); });
- strm.match([](double) { GTEST_FAIL(); },
- [](MathError me) { EXPECT_THAT(me, MathError::DivideByZero); });
- }
|