Example #1
0
def test_get_input_from_console_eof_error() -> None:
    program = console.get_input_from_console(
        prompt="How much wood would a woodchuck chuck?",
        parse_value=ZIO.from_callable(str).map(int).catch(
            ValueError).either().to_callable(),
        default_value=None)

    exception = EOFError()

    mock_console = MockConsole(["bad", "input", exception])
    mock_system = MockSystem()
    with pytest.raises(SystemExit):
        unsafe_run(
            program.provide(
                ConsoleSystemEnvironment(console=mock_console,
                                         system=mock_system)))

    assert mock_console.effects == [
        console_effect.Input("How much wood would a woodchuck chuck?", "bad"),
        console_effect.Input("How much wood would a woodchuck chuck?",
                             "input"),
        console_effect.Input("How much wood would a woodchuck chuck?",
                             exception),
        console_effect.Print("")
    ]
    assert mock_console.user_input == []

    assert mock_system.effects == [system_effect.Exit(None)]
Example #2
0
def test_from_callable() -> None:
    def _f(arg_1: int, arg_2: str, *, arg_3: float) -> str:
        return f"{arg_1} {arg_2} {arg_3}"

    program = ZIO.from_callable(_f)
    assert unsafe_run(program.provide(FunctionArguments(
        42, "foo", arg_3=3.14))) == "42 foo 3.14"
Example #3
0
 def ask(self, prompt: str, default: Literal['y', 'n'],
         do: ZIOMonad[System, NoReturn]) -> ZIO[System, NoReturn, bool]:
     default_str = 'Y/n' if default == 'y' else 'y/N'
     choice = do << self.get_input_from_console(
         prompt=f"{prompt} [{default_str}]: ",
         parse_value=(ZIO.from_callable(str).map(str.lower).require(
             lambda s: s in {'y', 'n'},
             lambda s: s).either().to_callable()),
         default_value=default)
     return ZIO.succeed(choice == 'y')
Example #4
0
def prog(
    do: ZIOMonad[ConsoleSystemEnvironment, NoReturn]
) -> ZIO[ConsoleSystemEnvironment, NoReturn, int]:
    age = do << console.get_input_from_console(
        prompt="How old are you?\n",
        parse_value=ZIO.from_callable(str).map(int).catch(
            ValueError).either().to_callable(),
        default_value=21)
    do << console.print(f"You are {age} years old.")
    return ZIO.succeed(age)
Example #5
0
def test_from_to_callable_1() -> None:
    class Cat:
        def meow(self, *, volume: int) -> str:
            if volume < 10:
                return "meow"
            else:
                return "MEOW!"

    meow_to_callable = (Environment[Cat]().map(lambda cat: ZIO.from_callable(
        cat.meow)).swap_environments().to_callable())

    assert unsafe_run(meow_to_callable(volume=11).provide(Cat())) == "MEOW!"
Example #6
0
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"))
Example #7
0
def test_get_input_from_console_1() -> None:
    program = console.get_input_from_console(
        prompt="How much wood would a woodchuck chuck?",
        parse_value=ZIO.from_callable(str).map(int).catch(
            ValueError).either().to_callable(),
        default_value=None)

    mock_console = MockConsole(["42"])
    mock_system = MockSystem()

    output = unsafe_run(
        program.provide(
            ConsoleSystemEnvironment(console=mock_console,
                                     system=mock_system)))
    assert output == 42
    assert mock_console.effects == [
        console_effect.Input("How much wood would a woodchuck chuck?", "42")
    ]
    assert mock_console.user_input == []
Example #8
0
    def effects(
            self) -> List[Union[console_effect.Print, console_effect.Input]]:
        return self._effects

    @property
    def user_input(self) -> List[Union[EOFError, KeyboardInterrupt, str]]:
        return self._user_input


class HasConsole(Protocol):
    @property
    def console(self) -> Console:
        pass  # pragma: nocover


print = (Environment[HasConsole]().map(lambda env: ZIO.from_callable(
    env.console.print).flatten()).swap_environments().to_callable())

input = (Environment[HasConsole]().map(lambda env: ZIO.from_callable(
    env.console.input).flatten()).swap_environments().to_callable())


class HasConsoleSystem(HasConsole, HasSystem, Protocol):
    pass


def get_input_from_console(
        prompt: str, parse_value: Callable[[str], Either[E, A]],
        default_value: Optional[A]) -> ZIO[HasConsoleSystem, NoReturn, A]:
    return (Environment[HasConsoleSystem]
            ().flat_map(lambda env: env.console.get_input_from_console(
                prompt, parse_value, default_value).provide(env.system)))
Example #9
0
def test_to_callable() -> None:
    def _f(arg_1: int, arg_2: str, *, arg_3: float) -> str:
        return f"{arg_1} {arg_2} {arg_3}"

    g = ZIO.from_callable(_f).to_callable()
    assert g(42, "foo", arg_3=3.14) == "42 foo 3.14"