def test_zio_lshift_2() -> None: def _kaboom(x: object) -> Either[NoReturn, int]: raise Bippy assert ((ZIO.succeed(100) << ZIO.succeed(1) << ZIO.succeed(2) << ZIO(_kaboom) << ZIO.succeed(3)).flat_map(lambda x: ZIO.succeed( f"The result is: {x}")).catch(Bippy))._run( ()) == Left(Bippy())
def test_asserting_4() -> None: assert unsafe_run(Environment[str]().asserting( lambda s: s.startswith("x"), lambda s: FooException(f"{s} doesn't start with x")).catch( BarException).asserting( lambda s: s.endswith("x"), lambda s: BarException(f"{s} doesn't end with x")).catch( FooException).either().provide("hello")) == Left( FooException("hello doesn't start with x"))
def test_zio_map_error_1() -> None: count = 0 def _impure_function(x: int) -> int: nonlocal count count += 1 return x + 1 assert (ZIO.fail(100).map_error(_impure_function).map_error( _impure_function).map_error(_impure_function).map_error( lambda x: f"The result is: {x}")._run( ())) == Left("The result is: 103") assert count == 3
def test_from_to_callable_2() -> None: @dataclass(frozen=True) class SomeException(Exception): message: str class SomeAPI: def thing_that_may_fail(self, *, bippy: str) -> int: raise SomeException("Murphy's Law") safer_thing = (Environment[SomeAPI]().map( lambda api: (ZIO.from_callable(api.thing_that_may_fail).catch( SomeException).either())).swap_environments().to_callable()) assert unsafe_run(safer_thing(bippy="bippy").provide(SomeAPI())) == Left( SomeException("Murphy's Law"))
def test_zio_flatten_2() -> None: count = 0 def _impure_function(x: int) -> ZIO[object, NoReturn, int]: nonlocal count count += 1 return ZIO.succeed(x + 1) def _kaboom(x: int) -> ZIO[object, NoReturn, int]: raise Bippy assert (ZIO.succeed(100).flat_map(_impure_function).flat_map( _kaboom).flat_map(_impure_function).flat_map(_impure_function).map( lambda x: ZIO.succeed(f"The result is: {x}")).catch( Bippy).flatten()._run(())) == Left(Bippy()) assert count == 1
def test_zio_map_error_2() -> None: count = 0 def _impure_function(x: int) -> int: nonlocal count count += 1 return x + 1 def _kaboom(x: int) -> int: raise Bippy assert (ZIO.fail(100).map_error(_impure_function).map_error(_kaboom). map_error(_impure_function).map_error(_impure_function).map_error( lambda x: f"The result is: {x}").catch(Bippy)._run( ())) == Left(Bippy()) assert count == 1
def test_to_union() -> None: # The point of this test is to ensure that mypy's type inference works # properly, ergo we prefer to not parametrize it. def foo(x: Union[int, str]) -> bool: return isinstance(x, int) or isinstance(x, str) e: Either[int, str] = Left(42) assert e.to_union() == 42 assert foo(e.to_union()) e = Right("hello") assert e.to_union() == "hello" assert foo(e.to_union()) # mypy should properly unify Union[NoReturn, X] for all types X. assert Either.left(42).to_union() + 1 == 43 assert len(Either.right("hello").to_union()) == len("hello")
def test_zio_effect_failure() -> None: def _impure_function() -> None: raise Bippy program = ZIO.effect(_impure_function) assert program._run(()) == Left(Bippy())
def test_asserting_2() -> None: assert unsafe_run(Environment[str]().asserting( lambda s: s.startswith("x"), lambda s: FooException(f"Oh noes: {s}")).catch( FooException).either().provide("hello")) == Left( FooException("Oh noes: hello"))
def test_zio_fail() -> None: assert ZIO.fail(42)._run(()) == Left(42)
def fail(e: EE) -> "ZIO[object, EE, NoReturn]": return ZIO(lambda _: Left(e))
def test_flatten_left() -> None: x: Either[str, Either[str, int]] = Either.left("asdf") assert x.flatten() == Left("asdf")
def test_zio_access_m_2() -> None: accessor: Callable[[str], ZIO[object, str, int]] = lambda s: ZIO.fail("oops") assert ZIO.access_m(accessor)._run("hello") == Left("oops")
assert Environment[int]()._run(42) == Right(42) def test_environment_2() -> None: assert Environment[int]().provide(42)._run(()) == Right(42) def test_environment_3() -> None: assert Environment[int]().provide(42).provide("asdf")._run(()) == Right(42) @pytest.mark.parametrize( "program,environment,expected_result", [ (ZIO.succeed(42), None, Right(42)), (ZIO.fail(Bippy()), None, Left(Bippy)), (ZIO.effect(lambda: 42), None, Right(42)), (ZIO.effect(lambda: _raise(Bippy())), None, Left(Bippy)), # type: ignore (ZIO.effect_catch(lambda: 42, Bippy), None, Right(42)), (ZIO.effect_catch(lambda: _raise(Bippy()), Bippy), None, Left(Bippy)), # type: ignore (ZIO.effect_catch(lambda: _raise(Bippy()), NotBippy), None, Left(Bippy)), # type: ignore (ZIO.succeed(42).catch(Bippy), None, Right(42)), (ZIO.access(len), "hello", Right(5)), (ZIO.access_m(lambda s: ZIO.succeed(len(s))), "hello", Right(5)), # type: ignore (ZIO.access_m(lambda s: ZIO.fail(Bippy())), "hello", Left(Bippy)), # type: ignore (ZIO.effect_total(lambda: 42), None, Right(42)),
def test_zio_effect_catch_2() -> None: def _impure_function() -> None: raise Bippy program = ZIO.effect_catch(_impure_function, Bippy) assert program._run(()) == Left(Bippy())
from typing import Callable, NoReturn, Type, TypeVar, Union import pytest from ziopy.either import Any, Either, EitherException, Left, Right A = TypeVar('A') B = TypeVar('B') C = TypeVar('C') X = TypeVar('X', bound=Exception) @pytest.mark.parametrize("input,expected", [ (42, Left(42)), ("asdf", Left("asdf")), ]) def test_either_left(input: Either[A, NoReturn], expected: Left[A]) -> None: x = Either.left(input) assert x == x.to_left() == expected with pytest.raises(TypeError): x.to_right() # type: ignore @pytest.mark.parametrize("input,expected", [ (42, Right(42)), ("asdf", Right("asdf")), ]) def test_either_right(input: Either[A, NoReturn], expected: Right[A]) -> None: x = Either.right(input) assert x == x.to_right() == expected
def test_zio_zip_3() -> None: assert ZIO.succeed("a").zip(ZIO.fail(42))._run(()) == Left(42)
def test_zio_either_2() -> None: assert ZIO.fail("a").either()._run(()) == Right(Left("a"))
@monadic def _q2(do: ZIOMonad[object, NoReturn]) -> ZIO[object, NoReturn, int]: result = do << ZIO.succeed(42) return ZIO.succeed(result) EQ2: Final = Equiv(ZIO.succeed(42), _q2(), (), Right(42)) @monadic def _q3(do: ZIOMonad[object, Bippy]) -> ZIO[object, Bippy, int]: do << ZIO.fail(Bippy()) return ZIO.succeed(42) EQ3: Final = Equiv(ZIO.fail(Bippy()), _q3(), (), Left(Bippy())) @monadic def _q4(do: ZIOMonad[object, Exception]) -> ZIO[object, Exception, int]: result = do << ZIO.effect(lambda: 42) return ZIO.succeed(result) EQ4: Final = Equiv(ZIO.effect(lambda: 42), _q4(), (), Right(42)) @monadic def _q5(do: ZIOMonad[object, Exception]) -> ZIO[object, Exception, int]: do << ZIO.effect(lambda: _raise(Bippy())) # type: ignore return ZIO.succeed(42)