| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- //
- // either_stream.t.h
- // optional.stream
- //
- // Created by Sam Jaffe on 1/30/17.
- //
- #pragma once
- #include <cxxtest/TestSuite.h>
- #include "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));
- }
- }
- class either_stream_TestSuite : public CxxTest::TestSuite {
- public:
- void test_either_becomes_error() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- strm.flatmap([](double d) { return divide(d, 0); })
- .match([](double) { TS_FAIL("Expected Error Type"); },
- [](MathError e) { TS_ASSERT_EQUALS( MathError::DivideByZero, e ); });
- }
-
- void test_either_computes_result() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- strm.map([](double d) { return multiply(d, 10.0); })
- .match([](double d) { TS_ASSERT_DELTA(10.0, d, 0.00001); },
- [](MathError) { TS_FAIL("Expected Value"); });
- }
-
- void test_either_computes_result2() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- bool is_error = strm.map([](double d) { return multiply(d, 10.0); })
- .match([](double) { return false; },
- [](MathError) { return true; });
- TS_ASSERT(!is_error);
- }
-
- void test_either_propogates_error() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- strm.flatmap([](double d) { return divide(d, 0); })
- .map([](double) { TS_FAIL("Operating on bad data"); return 0; })
- .match([](double) { TS_FAIL("Expected Error Type"); },
- [](MathError e) { TS_ASSERT_EQUALS( MathError::DivideByZero, e ); });
- }
-
- void test_either_propogates_same_error() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- strm.flatmap([](double d) { return log(1.0, d); })
- .flatmap([](double d) { return log(d, 1.0); })
- .match([](double) { TS_FAIL("Expected Error Type"); },
- [](MathError e) { TS_ASSERT_EQUALS( MathError::DivideByZero, e ); });
- }
- void test_either_propogates_same_error2() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- strm.flatmap([](double d) { return log(0.0, d); })
- .flatmap([](double d) { return log(d, 1.0); })
- .match([](double) { TS_FAIL("Expected Error Type"); },
- [](MathError e) { TS_ASSERT_EQUALS( MathError::DomainError, e ); });
- }
-
- void test_either_propogates_same_error3() {
- auto strm = stream::either::make_stream<MathObject>(1.0);
- bool is_error = strm.flatmap([](double d) { return log(0.0, d); })
- .flatmap([](double d) { return log(d, 1.0); })
- .match([](double) { return false; },
- [](MathError) { return true; });
- TS_ASSERT(is_error);
- }
- };
|