def test_result_bind_piped(x: int, y: int): xs: Result[int, str] = Ok(x) mapper: Callable[[int], Result[int, str]] = lambda x: Ok(x + y) ys = xs.pipe(result.bind(mapper)) for value in ys.match(Ok[int, str]): assert Ok(value) == mapper(x) break else: assert False
def test_pipeline_works(): fn: Callable[[int], Result[int, Exception]] = lambda x: Ok(x * 10) gn: Callable[[int], Result[int, Exception]] = lambda x: Ok(x + 10) hn = pipeline( fn, gn, ) assert hn(42) == Ok(430)
def test_result_traverse_ok(xs: List[int]): ys: List[Result[int, str]] = [Ok(x) for x in xs] zs = sequence(ys) for value in zs.match(Ok[List[int], str]): assert sum(value) == sum(xs) break else: assert False
def test_catch_with_effect_ok(): @catch(exception=TypeError) @effect.result def fn(a: int) -> Generator[int, int, int]: b = yield from Ok(42) return a + b result = fn(1) assert result == Ok(43)
def test_result_traverse_error(xs: List[int]): error = "Do'h" ys: List[Result[int, str]] = [ Ok(x) if i == 3 else Error(error) for x, i in enumerate(xs) ] zs = sequence(ys) for err in zs.match(Error[int, str]): assert err == error
def test_result_match_ok(): xs: Result[int, str] = Ok(42) with match(xs) as case: for x in case(Ok[int, str]): assert x == 42 break else: assert False
def test_result_map_piped(x: int, y: int): xs: Result[int, Exception] = Ok(x) mapper: Callable[[int], int] = lambda x: x + y ys = xs.pipe(result.map(mapper)) # NOTE: shows type error for mypy for value in ys.match(Ok[int, Exception]): assert value == mapper(x) break else: assert False
def test_result_map_ok_fluent(x: int, y: int): xs: Result[int, Exception] = Ok(x) mapper: Callable[[int], int] = lambda x: x + y ys = xs.map(mapper) for value in ys.match(Ok[int, Exception]): assert value == mapper(x) break else: assert False
def test_pipeline_error(): error: Result[int, str] = Error("failed") fn: Callable[[int], Result[int, str]] = lambda x: Ok(x * 10) gn: Callable[[int], Result[int, str]] = lambda x: error hn = pipeline( fn, gn, ) assert hn(42) == error
def test_result_ok_chained_map(x: int, y: int): xs: Result[int, Exception] = Ok(x) mapper1: Callable[[int], int] = lambda x: x + y mapper2: Callable[[int], int] = lambda x: x * 10 ys = xs.map(mapper1).map(mapper2) for value in ys.match(Ok[int, Exception]): assert value == mapper2(mapper1(x)) break else: assert False
def test_result_ok(): xs: Result[int, str] = Ok(42) assert isinstance(xs, Result) assert xs.is_ok() assert not xs.is_error() assert str(xs) == "Ok 42" for x in xs.match(Ok[int, str]): assert x == 42 break else: assert False
def test_result_ok_not_equals_error(x: int): assert not Ok(x) == Error(x) assert not Error(x) == Ok(x)
def test_result_ok_equals_ok(x: int, y: int): xs: Result[int, Exception] = Ok(x) ys: Result[int, Exception] = Ok(y) assert xs == ys if x == y else xs != ys
def test_result_ok_iterate(): for x in Ok(42): assert x == 42
def test_pipeline_none(): hn = pipeline() assert hn(42) == Ok(42)
def test_catch_wraps_ok(): @catch(exception=ValueError) def add(a: int, b: int) -> Any: return a + b assert add(3, 4) == Ok(7)
def fn() -> Generator[int, int, int]: x = yield from Ok(42) return x + 1
def fn(a: int) -> Generator[int, int, int]: b = yield from Ok(42) return a + b
def fn() -> Generator[int, int, int]: x = yield 42 y = yield from Ok(43) return x + y
def fn(a: int) -> Generator[str, str, int]: b = yield from Ok("hello") return a + b # type: ignore (by design)
def fn() -> Generator[int, int, int]: _ = yield from Ok(42) raise error