Marco Ricci commited on 2025-04-09 19:16:36
Zeige 5 geänderte Dateien mit 348 Einfügungen und 368 Löschungen.
Instead of using `click.testing.CliRunner` directly and transforming the result, wrap the runner in a new class that does the necessary transformations on the result automatically. This indirection of the CLI runner also allows the wrapper to cope with (some) incompatible changes in `click` across versions, or even eventually swap out the underlying implementation completely. As a first incompatibility to bridge, `click` 8.2.0 (currently in beta) merges many bad or incomplete fixes for long-standing issues, but with no regard to backward compatibility. Of particular relevance, `click.testing.CliRunner` no longer accepts the `mix_stderr` argument,[^1] and the meanings of the `output` and the `stdout` attribute of `click.testing.Result` have changed.[^2] These two incompatibilities are handled by the wrapper. [^1]: This breaks practically every call to the runner: `mix_stderr` defaults to `True`, thus the default behavior is to mangle the output streams. Why would you want that, in your testing machinery no less, where automatically mangling or discarding information behind the scenes is detrimental to debugging?! As a consequence, `mix_stderr` *has* to be specified if you want output streams not to be mangled, and if you want them to be mangled, you *should* specify `mix_stderr` explicitly. So basically, you always specify `mix_stderr`. And thus removing the (definition of the) `mix_stderr` argument breaks practically every call to the runner. [^2]: This is complementary to the removal of the `mix_stderr` argument: the mixed output is now always stored in the `output` attribute, and the `stdout` is the true standard output. Of course, this contradicts the previous use of `output` and `stdout`, where `output` was the true standard output, and `stdout` was a convenience alias via an extra layer of redirection.
... | ... |
@@ -19,12 +19,13 @@ import stat |
19 | 19 |
import tempfile |
20 | 20 |
import types |
21 | 21 |
import zipfile |
22 |
-from typing import TYPE_CHECKING |
|
22 |
+from typing import TYPE_CHECKING, TypedDict |
|
23 | 23 |
|
24 |
+import click.testing |
|
24 | 25 |
import hypothesis |
25 | 26 |
import pytest |
26 | 27 |
from hypothesis import strategies |
27 |
-from typing_extensions import NamedTuple, Self, assert_never |
|
28 |
+from typing_extensions import NamedTuple, assert_never |
|
28 | 29 |
|
29 | 30 |
from derivepassphrase import _types, cli, ssh_agent, vault |
30 | 31 |
from derivepassphrase._internals import cli_helpers, cli_machinery |
... | ... |
@@ -35,8 +36,8 @@ if TYPE_CHECKING: |
35 | 36 |
import socket |
36 | 37 |
from collections.abc import Callable, Iterator, Mapping, Sequence |
37 | 38 |
from contextlib import AbstractContextManager |
39 |
+ from typing import IO, NotRequired |
|
38 | 40 |
|
39 |
- import click.testing |
|
40 | 41 |
from typing_extensions import Any |
41 | 42 |
|
42 | 43 |
|
... | ... |
@@ -1699,7 +1700,7 @@ def phrase_from_key( |
1699 | 1700 |
@contextlib.contextmanager |
1700 | 1701 |
def isolated_config( |
1701 | 1702 |
monkeypatch: pytest.MonkeyPatch, |
1702 |
- runner: click.testing.CliRunner, |
|
1703 |
+ runner: CliRunner, |
|
1703 | 1704 |
main_config_str: str | None = None, |
1704 | 1705 |
) -> Iterator[None]: |
1705 | 1706 |
"""Provide an isolated configuration setup, as a context. |
... | ... |
@@ -1752,7 +1753,7 @@ def isolated_config( |
1752 | 1753 |
@contextlib.contextmanager |
1753 | 1754 |
def isolated_vault_config( |
1754 | 1755 |
monkeypatch: pytest.MonkeyPatch, |
1755 |
- runner: click.testing.CliRunner, |
|
1756 |
+ runner: CliRunner, |
|
1756 | 1757 |
vault_config: Any, |
1757 | 1758 |
main_config_str: str | None = None, |
1758 | 1759 |
) -> Iterator[None]: |
... | ... |
@@ -1790,7 +1791,7 @@ def isolated_vault_config( |
1790 | 1791 |
@contextlib.contextmanager |
1791 | 1792 |
def isolated_vault_exporter_config( |
1792 | 1793 |
monkeypatch: pytest.MonkeyPatch, |
1793 |
- runner: click.testing.CliRunner, |
|
1794 |
+ runner: CliRunner, |
|
1794 | 1795 |
vault_config: str | bytes | None = None, |
1795 | 1796 |
vault_key: str | None = None, |
1796 | 1797 |
) -> Iterator[None]: |
... | ... |
@@ -1949,18 +1950,9 @@ class ReadableResult(NamedTuple): |
1949 | 1950 |
|
1950 | 1951 |
exception: BaseException | None |
1951 | 1952 |
exit_code: int |
1952 |
- output: str |
|
1953 |
+ stdout: str |
|
1953 | 1954 |
stderr: str |
1954 | 1955 |
|
1955 |
- @classmethod |
|
1956 |
- def parse(cls, r: click.testing.Result, /) -> Self: |
|
1957 |
- """Return a readable result object, given a result.""" |
|
1958 |
- try: |
|
1959 |
- stderr = r.stderr |
|
1960 |
- except ValueError: |
|
1961 |
- stderr = r.output |
|
1962 |
- return cls(r.exception, r.exit_code, r.output or '', stderr or '') |
|
1963 |
- |
|
1964 | 1956 |
def clean_exit( |
1965 | 1957 |
self, *, output: str = '', empty_stderr: bool = False |
1966 | 1958 |
) -> bool: |
... | ... |
@@ -1979,7 +1971,7 @@ class ReadableResult(NamedTuple): |
1979 | 1971 |
and self.exit_code == 0 |
1980 | 1972 |
) |
1981 | 1973 |
) |
1982 |
- and (not output or output in self.output) |
|
1974 |
+ and (not output or output in self.stdout) |
|
1983 | 1975 |
and (not empty_stderr or not self.stderr) |
1984 | 1976 |
) |
1985 | 1977 |
|
... | ... |
@@ -2025,6 +2017,92 @@ class ReadableResult(NamedTuple): |
2025 | 2017 |
) |
2026 | 2018 |
|
2027 | 2019 |
|
2020 |
+class CliRunner: |
|
2021 |
+ """An abstracted CLI runner class. |
|
2022 |
+ |
|
2023 |
+ Intended to provide similar functionality and scope as the |
|
2024 |
+ [`click.testing.CliRunner`][] class, though not necessarily |
|
2025 |
+ `click`-specific. Also allows for seamless migration away from |
|
2026 |
+ `click`, if/when we decide this. |
|
2027 |
+ |
|
2028 |
+ """ |
|
2029 |
+ |
|
2030 |
+ _SUPPORTS_MIX_STDERR_ATTRIBUTE = not hasattr(click.testing, 'StreamMixer') |
|
2031 |
+ """ |
|
2032 |
+ True if and only if [`click.testing.CliRunner`][] supports the |
|
2033 |
+ `mix_stderr` attribute. It was removed in 8.2.0 in favor of the |
|
2034 |
+ [`click.testing.StreamMixer`][] class. |
|
2035 |
+ |
|
2036 |
+ See also |
|
2037 |
+ [`pallets/click#2523`](https://github.com/pallets/click/pull/2523). |
|
2038 |
+ """ |
|
2039 |
+ |
|
2040 |
+ def __init__( |
|
2041 |
+ self, |
|
2042 |
+ *, |
|
2043 |
+ mix_stderr: bool = False, |
|
2044 |
+ color: bool | None = None, |
|
2045 |
+ ) -> None: |
|
2046 |
+ self.color = color |
|
2047 |
+ self.mix_stderr = mix_stderr |
|
2048 |
+ |
|
2049 |
+ class MixStderrAttribute(TypedDict): |
|
2050 |
+ mix_stderr: NotRequired[bool] |
|
2051 |
+ |
|
2052 |
+ mix_stderr_args: MixStderrAttribute = ( |
|
2053 |
+ {'mix_stderr': mix_stderr} |
|
2054 |
+ if self._SUPPORTS_MIX_STDERR_ATTRIBUTE |
|
2055 |
+ else {} |
|
2056 |
+ ) |
|
2057 |
+ self.click_testing_clirunner = click.testing.CliRunner( |
|
2058 |
+ **mix_stderr_args |
|
2059 |
+ ) |
|
2060 |
+ |
|
2061 |
+ def invoke( |
|
2062 |
+ self, |
|
2063 |
+ cli: click.BaseCommand, |
|
2064 |
+ args: Sequence[str] | str | None = None, |
|
2065 |
+ input: str | bytes | IO[Any] | None = None, |
|
2066 |
+ env: Mapping[str, str | None] | None = None, |
|
2067 |
+ catch_exceptions: bool = True, |
|
2068 |
+ color: bool | None = None, |
|
2069 |
+ **extra: Any, |
|
2070 |
+ ) -> ReadableResult: |
|
2071 |
+ if color is None: # pragma: no cover |
|
2072 |
+ color = self.color if self.color is not None else False |
|
2073 |
+ raw_result = self.click_testing_clirunner.invoke( |
|
2074 |
+ cli, |
|
2075 |
+ args=args, |
|
2076 |
+ input=input, |
|
2077 |
+ env=env, |
|
2078 |
+ catch_exceptions=catch_exceptions, |
|
2079 |
+ color=color, |
|
2080 |
+ **extra, |
|
2081 |
+ ) |
|
2082 |
+ # In 8.2.0, r.stdout is no longer a property aliasing the |
|
2083 |
+ # `output` attribute, but rather the raw stdout value. |
|
2084 |
+ try: |
|
2085 |
+ stderr = raw_result.stderr |
|
2086 |
+ except ValueError: |
|
2087 |
+ stderr = raw_result.stdout |
|
2088 |
+ return ReadableResult( |
|
2089 |
+ raw_result.exception, |
|
2090 |
+ raw_result.exit_code, |
|
2091 |
+ (raw_result.stdout if not self.mix_stderr else raw_result.output) |
|
2092 |
+ or '', |
|
2093 |
+ stderr or '', |
|
2094 |
+ ) |
|
2095 |
+ return ReadableResult.parse(raw_result) |
|
2096 |
+ |
|
2097 |
+ def isolated_filesystem( |
|
2098 |
+ self, |
|
2099 |
+ temp_dir: str | os.PathLike[str] | None = None, |
|
2100 |
+ ) -> AbstractContextManager[str]: |
|
2101 |
+ return self.click_testing_clirunner.isolated_filesystem( |
|
2102 |
+ temp_dir=temp_dir |
|
2103 |
+ ) |
|
2104 |
+ |
|
2105 |
+ |
|
2028 | 2106 |
def parse_sh_export_line(line: str, *, env_name: str) -> str: |
2029 | 2107 |
"""Parse the output of typical SSH agents' SSH_AUTH_SOCK lines. |
2030 | 2108 |
|
... | ... |
@@ -317,8 +317,8 @@ def vault_config_exporter_shell_interpreter( # noqa: C901 |
317 | 317 |
*, |
318 | 318 |
prog_name_list: list[str] | None = None, |
319 | 319 |
command: click.BaseCommand | None = None, |
320 |
- runner: click.testing.CliRunner | None = None, |
|
321 |
-) -> Iterator[click.testing.Result]: |
|
320 |
+ runner: tests.CliRunner | None = None, |
|
321 |
+) -> Iterator[tests.ReadableResult]: |
|
322 | 322 |
"""A rudimentary sh(1) interpreter for `--export-as=sh` output. |
323 | 323 |
|
324 | 324 |
Assumes a script as emitted by `derivepassphrase vault |
... | ... |
@@ -335,7 +335,7 @@ def vault_config_exporter_shell_interpreter( # noqa: C901 |
335 | 335 |
if command is None: # pragma: no cover |
336 | 336 |
command = cli.derivepassphrase_vault |
337 | 337 |
if runner is None: # pragma: no cover |
338 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
338 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
339 | 339 |
n = len(prog_name_list) |
340 | 340 |
it = iter(script) |
341 | 341 |
while True: |
... | ... |
@@ -1666,7 +1666,7 @@ class TestAllCLI: |
1666 | 1666 |
TODO: Do we actually need this? What should we check for? |
1667 | 1667 |
|
1668 | 1668 |
""" |
1669 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1669 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1670 | 1670 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1671 | 1671 |
# with-statements. |
1672 | 1672 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1678,10 +1678,9 @@ class TestAllCLI: |
1678 | 1678 |
runner=runner, |
1679 | 1679 |
) |
1680 | 1680 |
) |
1681 |
- result_ = runner.invoke( |
|
1681 |
+ result = runner.invoke( |
|
1682 | 1682 |
cli.derivepassphrase, ['--help'], catch_exceptions=False |
1683 | 1683 |
) |
1684 |
- result = tests.ReadableResult.parse(result_) |
|
1685 | 1684 |
assert result.clean_exit( |
1686 | 1685 |
empty_stderr=True, output='currently implemented subcommands' |
1687 | 1686 |
), 'expected clean exit, and known help text' |
... | ... |
@@ -1696,7 +1695,7 @@ class TestAllCLI: |
1696 | 1695 |
TODO: Do we actually need this? What should we check for? |
1697 | 1696 |
|
1698 | 1697 |
""" |
1699 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1698 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1700 | 1699 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1701 | 1700 |
# with-statements. |
1702 | 1701 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1708,12 +1707,11 @@ class TestAllCLI: |
1708 | 1707 |
runner=runner, |
1709 | 1708 |
) |
1710 | 1709 |
) |
1711 |
- result_ = runner.invoke( |
|
1710 |
+ result = runner.invoke( |
|
1712 | 1711 |
cli.derivepassphrase, |
1713 | 1712 |
['export', '--help'], |
1714 | 1713 |
catch_exceptions=False, |
1715 | 1714 |
) |
1716 |
- result = tests.ReadableResult.parse(result_) |
|
1717 | 1715 |
assert result.clean_exit( |
1718 | 1716 |
empty_stderr=True, output='only available subcommand' |
1719 | 1717 |
), 'expected clean exit, and known help text' |
... | ... |
@@ -1728,7 +1726,7 @@ class TestAllCLI: |
1728 | 1726 |
TODO: Do we actually need this? What should we check for? |
1729 | 1727 |
|
1730 | 1728 |
""" |
1731 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1729 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1732 | 1730 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1733 | 1731 |
# with-statements. |
1734 | 1732 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1740,12 +1738,11 @@ class TestAllCLI: |
1740 | 1738 |
runner=runner, |
1741 | 1739 |
) |
1742 | 1740 |
) |
1743 |
- result_ = runner.invoke( |
|
1741 |
+ result = runner.invoke( |
|
1744 | 1742 |
cli.derivepassphrase, |
1745 | 1743 |
['export', 'vault', '--help'], |
1746 | 1744 |
catch_exceptions=False, |
1747 | 1745 |
) |
1748 |
- result = tests.ReadableResult.parse(result_) |
|
1749 | 1746 |
assert result.clean_exit( |
1750 | 1747 |
empty_stderr=True, output='Export a vault-native configuration' |
1751 | 1748 |
), 'expected clean exit, and known help text' |
... | ... |
@@ -1760,7 +1757,7 @@ class TestAllCLI: |
1760 | 1757 |
TODO: Do we actually need this? What should we check for? |
1761 | 1758 |
|
1762 | 1759 |
""" |
1763 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1760 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1764 | 1761 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1765 | 1762 |
# with-statements. |
1766 | 1763 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1772,12 +1769,11 @@ class TestAllCLI: |
1772 | 1769 |
runner=runner, |
1773 | 1770 |
) |
1774 | 1771 |
) |
1775 |
- result_ = runner.invoke( |
|
1772 |
+ result = runner.invoke( |
|
1776 | 1773 |
cli.derivepassphrase, |
1777 | 1774 |
['vault', '--help'], |
1778 | 1775 |
catch_exceptions=False, |
1779 | 1776 |
) |
1780 |
- result = tests.ReadableResult.parse(result_) |
|
1781 | 1777 |
assert result.clean_exit( |
1782 | 1778 |
empty_stderr=True, output='Passphrase generation:\n' |
1783 | 1779 |
), 'expected clean exit, and option groups in help text' |
... | ... |
@@ -1794,7 +1790,7 @@ class TestAllCLI: |
1794 | 1790 |
non_eager_arguments: list[str], |
1795 | 1791 |
) -> None: |
1796 | 1792 |
"""Eager options terminate option and argument processing.""" |
1797 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1793 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1798 | 1794 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1799 | 1795 |
# with-statements. |
1800 | 1796 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1806,12 +1802,11 @@ class TestAllCLI: |
1806 | 1802 |
runner=runner, |
1807 | 1803 |
) |
1808 | 1804 |
) |
1809 |
- result_ = runner.invoke( |
|
1805 |
+ result = runner.invoke( |
|
1810 | 1806 |
cli.derivepassphrase, |
1811 | 1807 |
[*command, *arguments, *non_eager_arguments], |
1812 | 1808 |
catch_exceptions=False, |
1813 | 1809 |
) |
1814 |
- result = tests.ReadableResult.parse(result_) |
|
1815 | 1810 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
1816 | 1811 |
|
1817 | 1812 |
@Parametrize.NO_COLOR |
... | ... |
@@ -1830,7 +1825,7 @@ class TestAllCLI: |
1830 | 1825 |
# Force color on if force_color. Otherwise force color off if |
1831 | 1826 |
# no_color. Otherwise set color if and only if we have a TTY. |
1832 | 1827 |
color = force_color or not no_color if isatty else force_color |
1833 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1828 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1834 | 1829 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1835 | 1830 |
# with-statements. |
1836 | 1831 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1846,14 +1841,13 @@ class TestAllCLI: |
1846 | 1841 |
monkeypatch.setenv('NO_COLOR', 'yes') |
1847 | 1842 |
if force_color: |
1848 | 1843 |
monkeypatch.setenv('FORCE_COLOR', 'yes') |
1849 |
- result_ = runner.invoke( |
|
1844 |
+ result = runner.invoke( |
|
1850 | 1845 |
cli.derivepassphrase, |
1851 | 1846 |
command_line, |
1852 | 1847 |
input=input, |
1853 | 1848 |
catch_exceptions=False, |
1854 | 1849 |
color=isatty, |
1855 | 1850 |
) |
1856 |
- result = tests.ReadableResult.parse(result_) |
|
1857 | 1851 |
assert ( |
1858 | 1852 |
not color |
1859 | 1853 |
or '\x1b[0m' in result.stderr |
... | ... |
@@ -1876,7 +1870,7 @@ class TestAllCLI: |
1876 | 1870 |
subcommands. |
1877 | 1871 |
|
1878 | 1872 |
""" |
1879 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1873 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1880 | 1874 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1881 | 1875 |
# with-statements. |
1882 | 1876 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1888,15 +1882,14 @@ class TestAllCLI: |
1888 | 1882 |
runner=runner, |
1889 | 1883 |
) |
1890 | 1884 |
) |
1891 |
- result_ = runner.invoke( |
|
1885 |
+ result = runner.invoke( |
|
1892 | 1886 |
cli.derivepassphrase, |
1893 | 1887 |
['--version'], |
1894 | 1888 |
catch_exceptions=False, |
1895 | 1889 |
) |
1896 |
- result = tests.ReadableResult.parse(result_) |
|
1897 | 1890 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
1898 |
- assert result.output.strip(), 'expected version output' |
|
1899 |
- version_data = parse_version_output(result.output) |
|
1891 |
+ assert result.stdout.strip(), 'expected version output' |
|
1892 |
+ version_data = parse_version_output(result.stdout) |
|
1900 | 1893 |
actually_known_schemes = dict.fromkeys(_types.DerivationScheme, True) |
1901 | 1894 |
subcommands = set(_types.Subcommand) |
1902 | 1895 |
assert version_data.derivation_schemes == actually_known_schemes |
... | ... |
@@ -1918,7 +1911,7 @@ class TestAllCLI: |
1918 | 1911 |
of subcommands. |
1919 | 1912 |
|
1920 | 1913 |
""" |
1921 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1914 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1922 | 1915 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1923 | 1916 |
# with-statements. |
1924 | 1917 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1930,15 +1923,14 @@ class TestAllCLI: |
1930 | 1923 |
runner=runner, |
1931 | 1924 |
) |
1932 | 1925 |
) |
1933 |
- result_ = runner.invoke( |
|
1926 |
+ result = runner.invoke( |
|
1934 | 1927 |
cli.derivepassphrase, |
1935 | 1928 |
['export', '--version'], |
1936 | 1929 |
catch_exceptions=False, |
1937 | 1930 |
) |
1938 |
- result = tests.ReadableResult.parse(result_) |
|
1939 | 1931 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
1940 |
- assert result.output.strip(), 'expected version output' |
|
1941 |
- version_data = parse_version_output(result.output) |
|
1932 |
+ assert result.stdout.strip(), 'expected version output' |
|
1933 |
+ version_data = parse_version_output(result.stdout) |
|
1942 | 1934 |
actually_known_formats: dict[str, bool] = { |
1943 | 1935 |
_types.ForeignConfigurationFormat.VAULT_STOREROOM: False, |
1944 | 1936 |
_types.ForeignConfigurationFormat.VAULT_V02: False, |
... | ... |
@@ -1967,7 +1959,7 @@ class TestAllCLI: |
1967 | 1959 |
configuration formats, and a list of available PEP 508 extras. |
1968 | 1960 |
|
1969 | 1961 |
""" |
1970 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
1962 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
1971 | 1963 |
# TODO(the-13th-letter): Rewrite using parenthesized |
1972 | 1964 |
# with-statements. |
1973 | 1965 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -1979,15 +1971,14 @@ class TestAllCLI: |
1979 | 1971 |
runner=runner, |
1980 | 1972 |
) |
1981 | 1973 |
) |
1982 |
- result_ = runner.invoke( |
|
1974 |
+ result = runner.invoke( |
|
1983 | 1975 |
cli.derivepassphrase, |
1984 | 1976 |
['export', 'vault', '--version'], |
1985 | 1977 |
catch_exceptions=False, |
1986 | 1978 |
) |
1987 |
- result = tests.ReadableResult.parse(result_) |
|
1988 | 1979 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
1989 |
- assert result.output.strip(), 'expected version output' |
|
1990 |
- version_data = parse_version_output(result.output) |
|
1980 |
+ assert result.stdout.strip(), 'expected version output' |
|
1981 |
+ version_data = parse_version_output(result.stdout) |
|
1991 | 1982 |
actually_known_formats: dict[str, bool] = {} |
1992 | 1983 |
actually_enabled_extras: set[str] = set() |
1993 | 1984 |
with contextlib.suppress(ModuleNotFoundError): |
... | ... |
@@ -2021,7 +2012,7 @@ class TestAllCLI: |
2021 | 2012 |
first paragraph. |
2022 | 2013 |
|
2023 | 2014 |
""" |
2024 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2015 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2025 | 2016 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2026 | 2017 |
# with-statements. |
2027 | 2018 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2033,15 +2024,14 @@ class TestAllCLI: |
2033 | 2024 |
runner=runner, |
2034 | 2025 |
) |
2035 | 2026 |
) |
2036 |
- result_ = runner.invoke( |
|
2027 |
+ result = runner.invoke( |
|
2037 | 2028 |
cli.derivepassphrase, |
2038 | 2029 |
['vault', '--version'], |
2039 | 2030 |
catch_exceptions=False, |
2040 | 2031 |
) |
2041 |
- result = tests.ReadableResult.parse(result_) |
|
2042 | 2032 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
2043 |
- assert result.output.strip(), 'expected version output' |
|
2044 |
- version_data = parse_version_output(result.output) |
|
2033 |
+ assert result.stdout.strip(), 'expected version output' |
|
2034 |
+ version_data = parse_version_output(result.stdout) |
|
2045 | 2035 |
features: dict[str, bool] = { |
2046 | 2036 |
_types.Feature.SSH_KEY: hasattr(socket, 'AF_UNIX'), |
2047 | 2037 |
} |
... | ... |
@@ -2059,7 +2049,7 @@ class TestCLI: |
2059 | 2049 |
self, |
2060 | 2050 |
) -> None: |
2061 | 2051 |
"""The `--help` option emits help text.""" |
2062 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2052 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2063 | 2053 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2064 | 2054 |
# with-statements. |
2065 | 2055 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2071,12 +2061,11 @@ class TestCLI: |
2071 | 2061 |
runner=runner, |
2072 | 2062 |
) |
2073 | 2063 |
) |
2074 |
- result_ = runner.invoke( |
|
2064 |
+ result = runner.invoke( |
|
2075 | 2065 |
cli.derivepassphrase_vault, |
2076 | 2066 |
['--help'], |
2077 | 2067 |
catch_exceptions=False, |
2078 | 2068 |
) |
2079 |
- result = tests.ReadableResult.parse(result_) |
|
2080 | 2069 |
assert result.clean_exit( |
2081 | 2070 |
empty_stderr=True, output='Passphrase generation:\n' |
2082 | 2071 |
), 'expected clean exit, and option groups in help text' |
... | ... |
@@ -2090,7 +2079,7 @@ class TestCLI: |
2090 | 2079 |
self, |
2091 | 2080 |
) -> None: |
2092 | 2081 |
"""The `--version` option emits version information.""" |
2093 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2082 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2094 | 2083 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2095 | 2084 |
# with-statements. |
2096 | 2085 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2102,12 +2091,11 @@ class TestCLI: |
2102 | 2091 |
runner=runner, |
2103 | 2092 |
) |
2104 | 2093 |
) |
2105 |
- result_ = runner.invoke( |
|
2094 |
+ result = runner.invoke( |
|
2106 | 2095 |
cli.derivepassphrase_vault, |
2107 | 2096 |
['--version'], |
2108 | 2097 |
catch_exceptions=False, |
2109 | 2098 |
) |
2110 |
- result = tests.ReadableResult.parse(result_) |
|
2111 | 2099 |
assert result.clean_exit(empty_stderr=True, output=cli.PROG_NAME), ( |
2112 | 2100 |
'expected clean exit, and program name in version text' |
2113 | 2101 |
) |
... | ... |
@@ -2123,7 +2111,7 @@ class TestCLI: |
2123 | 2111 |
"""Named character classes can be disabled on the command-line.""" |
2124 | 2112 |
option = f'--{charset_name}' |
2125 | 2113 |
charset = vault.Vault.CHARSETS[charset_name].decode('ascii') |
2126 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2114 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2127 | 2115 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2128 | 2116 |
# with-statements. |
2129 | 2117 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2138,16 +2126,15 @@ class TestCLI: |
2138 | 2126 |
monkeypatch.setattr( |
2139 | 2127 |
cli_helpers, 'prompt_for_passphrase', tests.auto_prompt |
2140 | 2128 |
) |
2141 |
- result_ = runner.invoke( |
|
2129 |
+ result = runner.invoke( |
|
2142 | 2130 |
cli.derivepassphrase_vault, |
2143 | 2131 |
[option, '0', '-p', '--', DUMMY_SERVICE], |
2144 | 2132 |
input=DUMMY_PASSPHRASE, |
2145 | 2133 |
catch_exceptions=False, |
2146 | 2134 |
) |
2147 |
- result = tests.ReadableResult.parse(result_) |
|
2148 | 2135 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit:' |
2149 | 2136 |
for c in charset: |
2150 |
- assert c not in result.output, ( |
|
2137 |
+ assert c not in result.stdout, ( |
|
2151 | 2138 |
f'derived password contains forbidden character {c!r}' |
2152 | 2139 |
) |
2153 | 2140 |
|
... | ... |
@@ -2155,7 +2142,7 @@ class TestCLI: |
2155 | 2142 |
self, |
2156 | 2143 |
) -> None: |
2157 | 2144 |
"""Character repetition can be disabled on the command-line.""" |
2158 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2145 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2159 | 2146 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2160 | 2147 |
# with-statements. |
2161 | 2148 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2170,21 +2157,20 @@ class TestCLI: |
2170 | 2157 |
monkeypatch.setattr( |
2171 | 2158 |
cli_helpers, 'prompt_for_passphrase', tests.auto_prompt |
2172 | 2159 |
) |
2173 |
- result_ = runner.invoke( |
|
2160 |
+ result = runner.invoke( |
|
2174 | 2161 |
cli.derivepassphrase_vault, |
2175 | 2162 |
['--repeat', '0', '-p', '--', DUMMY_SERVICE], |
2176 | 2163 |
input=DUMMY_PASSPHRASE, |
2177 | 2164 |
catch_exceptions=False, |
2178 | 2165 |
) |
2179 |
- result = tests.ReadableResult.parse(result_) |
|
2180 | 2166 |
assert result.clean_exit(empty_stderr=True), ( |
2181 | 2167 |
'expected clean exit and empty stderr' |
2182 | 2168 |
) |
2183 |
- passphrase = result.output.rstrip('\r\n') |
|
2169 |
+ passphrase = result.stdout.rstrip('\r\n') |
|
2184 | 2170 |
for i in range(len(passphrase) - 1): |
2185 | 2171 |
assert passphrase[i : i + 1] != passphrase[i + 1 : i + 2], ( |
2186 | 2172 |
f'derived password contains repeated character ' |
2187 |
- f'at position {i}: {result.output!r}' |
|
2173 |
+ f'at position {i}: {result.stdout!r}' |
|
2188 | 2174 |
) |
2189 | 2175 |
|
2190 | 2176 |
@Parametrize.CONFIG_WITH_KEY |
... | ... |
@@ -2193,7 +2179,7 @@ class TestCLI: |
2193 | 2179 |
config: _types.VaultConfig, |
2194 | 2180 |
) -> None: |
2195 | 2181 |
"""A stored configured SSH key will be used.""" |
2196 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2182 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2197 | 2183 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2198 | 2184 |
# with-statements. |
2199 | 2185 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2209,28 +2195,28 @@ class TestCLI: |
2209 | 2195 |
monkeypatch.setattr( |
2210 | 2196 |
vault.Vault, 'phrase_from_key', tests.phrase_from_key |
2211 | 2197 |
) |
2212 |
- result_ = runner.invoke( |
|
2198 |
+ result = runner.invoke( |
|
2213 | 2199 |
cli.derivepassphrase_vault, |
2214 | 2200 |
['--', DUMMY_SERVICE], |
2215 | 2201 |
catch_exceptions=False, |
2216 | 2202 |
) |
2217 |
- result = tests.ReadableResult.parse(result_) |
|
2218 | 2203 |
assert result.clean_exit(empty_stderr=True), ( |
2219 | 2204 |
'expected clean exit and empty stderr' |
2220 | 2205 |
) |
2221 |
- assert result_.stdout_bytes |
|
2222 |
- assert result_.stdout_bytes.rstrip(b'\n') != DUMMY_RESULT_PASSPHRASE, ( |
|
2223 |
- 'known false output: phrase-based instead of key-based' |
|
2224 |
- ) |
|
2225 |
- assert result_.stdout_bytes.rstrip(b'\n') == DUMMY_RESULT_KEY1, ( |
|
2226 |
- 'expected known output' |
|
2227 |
- ) |
|
2206 |
+ assert result.stdout |
|
2207 |
+ assert ( |
|
2208 |
+ result.stdout.rstrip('\n').encode('UTF-8') |
|
2209 |
+ != DUMMY_RESULT_PASSPHRASE |
|
2210 |
+ ), 'known false output: phrase-based instead of key-based' |
|
2211 |
+ assert ( |
|
2212 |
+ result.stdout.rstrip('\n').encode('UTF-8') == DUMMY_RESULT_KEY1 |
|
2213 |
+ ), 'expected known output' |
|
2228 | 2214 |
|
2229 | 2215 |
def test_204b_key_from_command_line( |
2230 | 2216 |
self, |
2231 | 2217 |
) -> None: |
2232 | 2218 |
"""An SSH key requested on the command-line will be used.""" |
2233 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2219 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2234 | 2220 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2235 | 2221 |
# with-statements. |
2236 | 2222 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2251,20 +2237,19 @@ class TestCLI: |
2251 | 2237 |
monkeypatch.setattr( |
2252 | 2238 |
vault.Vault, 'phrase_from_key', tests.phrase_from_key |
2253 | 2239 |
) |
2254 |
- result_ = runner.invoke( |
|
2240 |
+ result = runner.invoke( |
|
2255 | 2241 |
cli.derivepassphrase_vault, |
2256 | 2242 |
['-k', '--', DUMMY_SERVICE], |
2257 | 2243 |
input='1\n', |
2258 | 2244 |
catch_exceptions=False, |
2259 | 2245 |
) |
2260 |
- result = tests.ReadableResult.parse(result_) |
|
2261 | 2246 |
assert result.clean_exit(), 'expected clean exit' |
2262 |
- assert result_.stdout_bytes, 'expected program output' |
|
2263 |
- last_line = result_.stdout_bytes.splitlines(True)[-1] |
|
2264 |
- assert last_line.rstrip(b'\n') != DUMMY_RESULT_PASSPHRASE, ( |
|
2265 |
- 'known false output: phrase-based instead of key-based' |
|
2266 |
- ) |
|
2267 |
- assert last_line.rstrip(b'\n') == DUMMY_RESULT_KEY1, ( |
|
2247 |
+ assert result.stdout, 'expected program output' |
|
2248 |
+ last_line = result.stdout.splitlines(True)[-1] |
|
2249 |
+ assert ( |
|
2250 |
+ last_line.rstrip('\n').encode('UTF-8') != DUMMY_RESULT_PASSPHRASE |
|
2251 |
+ ), 'known false output: phrase-based instead of key-based' |
|
2252 |
+ assert last_line.rstrip('\n').encode('UTF-8') == DUMMY_RESULT_KEY1, ( |
|
2268 | 2253 |
'expected known output' |
2269 | 2254 |
) |
2270 | 2255 |
|
... | ... |
@@ -2277,7 +2262,7 @@ class TestCLI: |
2277 | 2262 |
key_index: int, |
2278 | 2263 |
) -> None: |
2279 | 2264 |
"""A command-line SSH key will override the configured key.""" |
2280 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2265 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2281 | 2266 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2282 | 2267 |
# with-statements. |
2283 | 2268 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2295,14 +2280,13 @@ class TestCLI: |
2295 | 2280 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
2296 | 2281 |
) |
2297 | 2282 |
monkeypatch.setattr(ssh_agent.SSHAgentClient, 'sign', tests.sign) |
2298 |
- result_ = runner.invoke( |
|
2283 |
+ result = runner.invoke( |
|
2299 | 2284 |
cli.derivepassphrase_vault, |
2300 | 2285 |
['-k', '--', DUMMY_SERVICE], |
2301 | 2286 |
input=f'{key_index}\n', |
2302 | 2287 |
) |
2303 |
- result = tests.ReadableResult.parse(result_) |
|
2304 | 2288 |
assert result.clean_exit(), 'expected clean exit' |
2305 |
- assert result.output, 'expected program output' |
|
2289 |
+ assert result.stdout, 'expected program output' |
|
2306 | 2290 |
assert result.stderr, 'expected stderr' |
2307 | 2291 |
assert 'Error:' not in result.stderr, ( |
2308 | 2292 |
'expected no error messages on stderr' |
... | ... |
@@ -2313,7 +2297,7 @@ class TestCLI: |
2313 | 2297 |
running_ssh_agent: tests.RunningSSHAgentInfo, |
2314 | 2298 |
) -> None: |
2315 | 2299 |
"""A command-line passphrase will override the configured key.""" |
2316 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2300 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2317 | 2301 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2318 | 2302 |
# with-statements. |
2319 | 2303 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2339,19 +2323,18 @@ class TestCLI: |
2339 | 2323 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
2340 | 2324 |
) |
2341 | 2325 |
monkeypatch.setattr(ssh_agent.SSHAgentClient, 'sign', tests.sign) |
2342 |
- result_ = runner.invoke( |
|
2326 |
+ result = runner.invoke( |
|
2343 | 2327 |
cli.derivepassphrase_vault, |
2344 | 2328 |
['--', DUMMY_SERVICE], |
2345 | 2329 |
catch_exceptions=False, |
2346 | 2330 |
) |
2347 |
- result = tests.ReadableResult.parse(result_) |
|
2348 | 2331 |
assert result.clean_exit(), 'expected clean exit' |
2349 |
- assert result_.stdout_bytes, 'expected program output' |
|
2350 |
- last_line = result_.stdout_bytes.splitlines(True)[-1] |
|
2351 |
- assert last_line.rstrip(b'\n') != DUMMY_RESULT_PASSPHRASE, ( |
|
2352 |
- 'known false output: phrase-based instead of key-based' |
|
2353 |
- ) |
|
2354 |
- assert last_line.rstrip(b'\n') == DUMMY_RESULT_KEY1, ( |
|
2332 |
+ assert result.stdout, 'expected program output' |
|
2333 |
+ last_line = result.stdout.splitlines(True)[-1] |
|
2334 |
+ assert ( |
|
2335 |
+ last_line.rstrip('\n').encode('UTF-8') != DUMMY_RESULT_PASSPHRASE |
|
2336 |
+ ), 'known false output: phrase-based instead of key-based' |
|
2337 |
+ assert last_line.rstrip('\n').encode('UTF-8') == DUMMY_RESULT_KEY1, ( |
|
2355 | 2338 |
'expected known output' |
2356 | 2339 |
) |
2357 | 2340 |
|
... | ... |
@@ -2364,7 +2347,7 @@ class TestCLI: |
2364 | 2347 |
command_line: list[str], |
2365 | 2348 |
) -> None: |
2366 | 2349 |
"""Configuring a passphrase atop an SSH key works, but warns.""" |
2367 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2350 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2368 | 2351 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2369 | 2352 |
# with-statements. |
2370 | 2353 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2382,15 +2365,14 @@ class TestCLI: |
2382 | 2365 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
2383 | 2366 |
) |
2384 | 2367 |
monkeypatch.setattr(ssh_agent.SSHAgentClient, 'sign', tests.sign) |
2385 |
- result_ = runner.invoke( |
|
2368 |
+ result = runner.invoke( |
|
2386 | 2369 |
cli.derivepassphrase_vault, |
2387 | 2370 |
command_line, |
2388 | 2371 |
input=DUMMY_PASSPHRASE, |
2389 | 2372 |
catch_exceptions=False, |
2390 | 2373 |
) |
2391 |
- result = tests.ReadableResult.parse(result_) |
|
2392 | 2374 |
assert result.clean_exit(), 'expected clean exit' |
2393 |
- assert not result.output.strip(), 'expected no program output' |
|
2375 |
+ assert not result.stdout.strip(), 'expected no program output' |
|
2394 | 2376 |
assert result.stderr, 'expected known error output' |
2395 | 2377 |
err_lines = result.stderr.splitlines(False) |
2396 | 2378 |
assert err_lines[0].startswith('Passphrase:') |
... | ... |
@@ -2422,7 +2404,7 @@ class TestCLI: |
2422 | 2404 |
) -> None: |
2423 | 2405 |
"""Service notes are printed, if they exist.""" |
2424 | 2406 |
hypothesis.assume('Error:' not in notes) |
2425 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2407 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2426 | 2408 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2427 | 2409 |
# with-statements. |
2428 | 2410 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2445,14 +2427,13 @@ class TestCLI: |
2445 | 2427 |
}, |
2446 | 2428 |
) |
2447 | 2429 |
) |
2448 |
- result_ = runner.invoke( |
|
2430 |
+ result = runner.invoke( |
|
2449 | 2431 |
cli.derivepassphrase_vault, |
2450 | 2432 |
['--', DUMMY_SERVICE], |
2451 | 2433 |
) |
2452 |
- result = tests.ReadableResult.parse(result_) |
|
2453 | 2434 |
assert result.clean_exit(), 'expected clean exit' |
2454 |
- assert result.output, 'expected program output' |
|
2455 |
- assert result.output.strip() == DUMMY_RESULT_PASSPHRASE.decode( |
|
2435 |
+ assert result.stdout, 'expected program output' |
|
2436 |
+ assert result.stdout.strip() == DUMMY_RESULT_PASSPHRASE.decode( |
|
2456 | 2437 |
'ascii' |
2457 | 2438 |
), 'expected known program output' |
2458 | 2439 |
assert result.stderr or not notes.strip(), 'expected stderr' |
... | ... |
@@ -2469,7 +2450,7 @@ class TestCLI: |
2469 | 2450 |
option: str, |
2470 | 2451 |
) -> None: |
2471 | 2452 |
"""Requesting invalidly many characters from a class fails.""" |
2472 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2453 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2473 | 2454 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2474 | 2455 |
# with-statements. |
2475 | 2456 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2482,13 +2463,12 @@ class TestCLI: |
2482 | 2463 |
) |
2483 | 2464 |
) |
2484 | 2465 |
for value in '-42', 'invalid': |
2485 |
- result_ = runner.invoke( |
|
2466 |
+ result = runner.invoke( |
|
2486 | 2467 |
cli.derivepassphrase_vault, |
2487 | 2468 |
[option, value, '-p', '--', DUMMY_SERVICE], |
2488 | 2469 |
input=DUMMY_PASSPHRASE, |
2489 | 2470 |
catch_exceptions=False, |
2490 | 2471 |
) |
2491 |
- result = tests.ReadableResult.parse(result_) |
|
2492 | 2472 |
assert result.error_exit(error='Invalid value'), ( |
2493 | 2473 |
'expected error exit and known error message' |
2494 | 2474 |
) |
... | ... |
@@ -2502,7 +2482,7 @@ class TestCLI: |
2502 | 2482 |
check_success: bool, |
2503 | 2483 |
) -> None: |
2504 | 2484 |
"""We require or forbid a service argument, depending on options.""" |
2505 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2485 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2506 | 2486 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2507 | 2487 |
# with-statements. |
2508 | 2488 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2518,13 +2498,12 @@ class TestCLI: |
2518 | 2498 |
monkeypatch.setattr( |
2519 | 2499 |
cli_helpers, 'prompt_for_passphrase', tests.auto_prompt |
2520 | 2500 |
) |
2521 |
- result_ = runner.invoke( |
|
2501 |
+ result = runner.invoke( |
|
2522 | 2502 |
cli.derivepassphrase_vault, |
2523 | 2503 |
options if service else [*options, '--', DUMMY_SERVICE], |
2524 | 2504 |
input=input, |
2525 | 2505 |
catch_exceptions=False, |
2526 | 2506 |
) |
2527 |
- result = tests.ReadableResult.parse(result_) |
|
2528 | 2507 |
if service is not None: |
2529 | 2508 |
err_msg = ( |
2530 | 2509 |
' requires a SERVICE' |
... | ... |
@@ -2557,13 +2536,12 @@ class TestCLI: |
2557 | 2536 |
monkeypatch.setattr( |
2558 | 2537 |
cli_helpers, 'prompt_for_passphrase', tests.auto_prompt |
2559 | 2538 |
) |
2560 |
- result_ = runner.invoke( |
|
2539 |
+ result = runner.invoke( |
|
2561 | 2540 |
cli.derivepassphrase_vault, |
2562 | 2541 |
[*options, '--', DUMMY_SERVICE] if service else options, |
2563 | 2542 |
input=input, |
2564 | 2543 |
catch_exceptions=False, |
2565 | 2544 |
) |
2566 |
- result = tests.ReadableResult.parse(result_) |
|
2567 | 2545 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
2568 | 2546 |
|
2569 | 2547 |
def test_211a_empty_service_name_causes_warning( |
... | ... |
@@ -2583,7 +2561,7 @@ class TestCLI: |
2583 | 2561 |
'An empty SERVICE is not supported by vault(1)', [record] |
2584 | 2562 |
) |
2585 | 2563 |
|
2586 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2564 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2587 | 2565 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2588 | 2566 |
# with-statements. |
2589 | 2567 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2599,12 +2577,11 @@ class TestCLI: |
2599 | 2577 |
monkeypatch.setattr( |
2600 | 2578 |
cli_helpers, 'prompt_for_passphrase', tests.auto_prompt |
2601 | 2579 |
) |
2602 |
- result_ = runner.invoke( |
|
2580 |
+ result = runner.invoke( |
|
2603 | 2581 |
cli.derivepassphrase_vault, |
2604 | 2582 |
['--config', '--length=30', '--', ''], |
2605 | 2583 |
catch_exceptions=False, |
2606 | 2584 |
) |
2607 |
- result = tests.ReadableResult.parse(result_) |
|
2608 | 2585 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
2609 | 2586 |
assert result.stderr is not None, 'expected known error output' |
2610 | 2587 |
assert all(map(is_expected_warning, caplog.record_tuples)), ( |
... | ... |
@@ -2615,13 +2592,12 @@ class TestCLI: |
2615 | 2592 |
'services': {}, |
2616 | 2593 |
}, 'requested configuration change was not applied' |
2617 | 2594 |
caplog.clear() |
2618 |
- result_ = runner.invoke( |
|
2595 |
+ result = runner.invoke( |
|
2619 | 2596 |
cli.derivepassphrase_vault, |
2620 | 2597 |
['--import', '-'], |
2621 | 2598 |
input=json.dumps({'services': {'': {'length': 40}}}), |
2622 | 2599 |
catch_exceptions=False, |
2623 | 2600 |
) |
2624 |
- result = tests.ReadableResult.parse(result_) |
|
2625 | 2601 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
2626 | 2602 |
assert result.stderr is not None, 'expected known error output' |
2627 | 2603 |
assert all(map(is_expected_warning, caplog.record_tuples)), ( |
... | ... |
@@ -2639,7 +2615,7 @@ class TestCLI: |
2639 | 2615 |
service: bool | None, |
2640 | 2616 |
) -> None: |
2641 | 2617 |
"""Incompatible options are detected.""" |
2642 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2618 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2643 | 2619 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2644 | 2620 |
# with-statements. |
2645 | 2621 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2651,13 +2627,12 @@ class TestCLI: |
2651 | 2627 |
runner=runner, |
2652 | 2628 |
) |
2653 | 2629 |
) |
2654 |
- result_ = runner.invoke( |
|
2630 |
+ result = runner.invoke( |
|
2655 | 2631 |
cli.derivepassphrase_vault, |
2656 | 2632 |
[*options, '--', DUMMY_SERVICE] if service else options, |
2657 | 2633 |
input=DUMMY_PASSPHRASE, |
2658 | 2634 |
catch_exceptions=False, |
2659 | 2635 |
) |
2660 |
- result = tests.ReadableResult.parse(result_) |
|
2661 | 2636 |
assert result.error_exit(error='mutually exclusive with '), ( |
2662 | 2637 |
'expected error exit and known error message' |
2663 | 2638 |
) |
... | ... |
@@ -2669,7 +2644,7 @@ class TestCLI: |
2669 | 2644 |
config: Any, |
2670 | 2645 |
) -> None: |
2671 | 2646 |
"""Importing a configuration works.""" |
2672 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2647 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2673 | 2648 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2674 | 2649 |
# with-statements. |
2675 | 2650 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2682,7 +2657,7 @@ class TestCLI: |
2682 | 2657 |
vault_config={'services': {}}, |
2683 | 2658 |
) |
2684 | 2659 |
) |
2685 |
- result_ = runner.invoke( |
|
2660 |
+ result = runner.invoke( |
|
2686 | 2661 |
cli.derivepassphrase_vault, |
2687 | 2662 |
['--import', '-'], |
2688 | 2663 |
input=json.dumps(config), |
... | ... |
@@ -2692,7 +2667,6 @@ class TestCLI: |
2692 | 2667 |
subsystem='vault' |
2693 | 2668 |
).read_text(encoding='UTF-8') |
2694 | 2669 |
config2 = json.loads(config_txt) |
2695 |
- result = tests.ReadableResult.parse(result_) |
|
2696 | 2670 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
2697 | 2671 |
assert config2 == config, 'config not imported correctly' |
2698 | 2672 |
assert not result.stderr or all( # pragma: no branch |
... | ... |
@@ -2730,7 +2704,7 @@ class TestCLI: |
2730 | 2704 |
_types.clean_up_falsy_vault_config_values(config2) |
2731 | 2705 |
# Reset caplog between hypothesis runs. |
2732 | 2706 |
caplog.clear() |
2733 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2707 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2734 | 2708 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2735 | 2709 |
# with-statements. |
2736 | 2710 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2743,7 +2717,7 @@ class TestCLI: |
2743 | 2717 |
vault_config={'services': {}}, |
2744 | 2718 |
) |
2745 | 2719 |
) |
2746 |
- result_ = runner.invoke( |
|
2720 |
+ result = runner.invoke( |
|
2747 | 2721 |
cli.derivepassphrase_vault, |
2748 | 2722 |
['--import', '-'], |
2749 | 2723 |
input=json.dumps(config), |
... | ... |
@@ -2753,7 +2727,6 @@ class TestCLI: |
2753 | 2727 |
subsystem='vault' |
2754 | 2728 |
).read_text(encoding='UTF-8') |
2755 | 2729 |
config3 = json.loads(config_txt) |
2756 |
- result = tests.ReadableResult.parse(result_) |
|
2757 | 2730 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
2758 | 2731 |
assert config3 == config2, 'config not imported correctly' |
2759 | 2732 |
assert not result.stderr or all( |
... | ... |
@@ -2765,7 +2738,7 @@ class TestCLI: |
2765 | 2738 |
self, |
2766 | 2739 |
) -> None: |
2767 | 2740 |
"""Importing an invalid config fails.""" |
2768 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2741 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2769 | 2742 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2770 | 2743 |
# with-statements. |
2771 | 2744 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2777,13 +2750,12 @@ class TestCLI: |
2777 | 2750 |
runner=runner, |
2778 | 2751 |
) |
2779 | 2752 |
) |
2780 |
- result_ = runner.invoke( |
|
2753 |
+ result = runner.invoke( |
|
2781 | 2754 |
cli.derivepassphrase_vault, |
2782 | 2755 |
['--import', '-'], |
2783 | 2756 |
input='null', |
2784 | 2757 |
catch_exceptions=False, |
2785 | 2758 |
) |
2786 |
- result = tests.ReadableResult.parse(result_) |
|
2787 | 2759 |
assert result.error_exit(error='Invalid vault config'), ( |
2788 | 2760 |
'expected error exit and known error message' |
2789 | 2761 |
) |
... | ... |
@@ -2792,7 +2764,7 @@ class TestCLI: |
2792 | 2764 |
self, |
2793 | 2765 |
) -> None: |
2794 | 2766 |
"""Importing an invalid config fails.""" |
2795 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2767 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2796 | 2768 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2797 | 2769 |
# with-statements. |
2798 | 2770 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2804,13 +2776,12 @@ class TestCLI: |
2804 | 2776 |
runner=runner, |
2805 | 2777 |
) |
2806 | 2778 |
) |
2807 |
- result_ = runner.invoke( |
|
2779 |
+ result = runner.invoke( |
|
2808 | 2780 |
cli.derivepassphrase_vault, |
2809 | 2781 |
['--import', '-'], |
2810 | 2782 |
input='This string is not valid JSON.', |
2811 | 2783 |
catch_exceptions=False, |
2812 | 2784 |
) |
2813 |
- result = tests.ReadableResult.parse(result_) |
|
2814 | 2785 |
assert result.error_exit(error='cannot decode JSON'), ( |
2815 | 2786 |
'expected error exit and known error message' |
2816 | 2787 |
) |
... | ... |
@@ -2819,7 +2790,7 @@ class TestCLI: |
2819 | 2790 |
self, |
2820 | 2791 |
) -> None: |
2821 | 2792 |
"""Importing an invalid config fails.""" |
2822 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2793 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2823 | 2794 |
# `isolated_vault_config` ensures the configuration is valid |
2824 | 2795 |
# JSON. So, to pass an actual broken configuration, we must |
2825 | 2796 |
# open the configuration file ourselves afterwards, inside the |
... | ... |
@@ -2841,12 +2812,11 @@ class TestCLI: |
2841 | 2812 |
'This string is not valid JSON.\n', encoding='UTF-8' |
2842 | 2813 |
) |
2843 | 2814 |
dname = cli_helpers.config_filename(subsystem=None) |
2844 |
- result_ = runner.invoke( |
|
2815 |
+ result = runner.invoke( |
|
2845 | 2816 |
cli.derivepassphrase_vault, |
2846 | 2817 |
['--import', os.fsdecode(dname)], |
2847 | 2818 |
catch_exceptions=False, |
2848 | 2819 |
) |
2849 |
- result = tests.ReadableResult.parse(result_) |
|
2850 | 2820 |
assert result.error_exit(error=os.strerror(errno.EISDIR)), ( |
2851 | 2821 |
'expected error exit and known error message' |
2852 | 2822 |
) |
... | ... |
@@ -2858,7 +2828,7 @@ class TestCLI: |
2858 | 2828 |
config: Any, |
2859 | 2829 |
) -> None: |
2860 | 2830 |
"""Exporting a configuration works.""" |
2861 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2831 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2862 | 2832 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2863 | 2833 |
# with-statements. |
2864 | 2834 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2876,7 +2846,7 @@ class TestCLI: |
2876 | 2846 |
) as outfile: |
2877 | 2847 |
# Ensure the config is written on one line. |
2878 | 2848 |
json.dump(config, outfile, indent=None) |
2879 |
- result_ = runner.invoke( |
|
2849 |
+ result = runner.invoke( |
|
2880 | 2850 |
cli.derivepassphrase_vault, |
2881 | 2851 |
['--export', '-'], |
2882 | 2852 |
catch_exceptions=False, |
... | ... |
@@ -2885,13 +2855,12 @@ class TestCLI: |
2885 | 2855 |
encoding='UTF-8' |
2886 | 2856 |
) as infile: |
2887 | 2857 |
config2 = json.load(infile) |
2888 |
- result = tests.ReadableResult.parse(result_) |
|
2889 | 2858 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
2890 | 2859 |
assert config2 == config, 'config not imported correctly' |
2891 | 2860 |
assert not result.stderr or all( # pragma: no branch |
2892 | 2861 |
map(is_harmless_config_import_warning, caplog.record_tuples) |
2893 | 2862 |
), 'unexpected error output' |
2894 |
- assert_vault_config_is_indented_and_line_broken(result.output) |
|
2863 |
+ assert_vault_config_is_indented_and_line_broken(result.stdout) |
|
2895 | 2864 |
|
2896 | 2865 |
@Parametrize.EXPORT_FORMAT_OPTIONS |
2897 | 2866 |
def test_214a_export_settings_no_stored_settings( |
... | ... |
@@ -2899,7 +2868,7 @@ class TestCLI: |
2899 | 2868 |
export_options: list[str], |
2900 | 2869 |
) -> None: |
2901 | 2870 |
"""Exporting the default, empty config works.""" |
2902 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2871 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2903 | 2872 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2904 | 2873 |
# with-statements. |
2905 | 2874 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2914,7 +2883,7 @@ class TestCLI: |
2914 | 2883 |
cli_helpers.config_filename(subsystem='vault').unlink( |
2915 | 2884 |
missing_ok=True |
2916 | 2885 |
) |
2917 |
- result_ = runner.invoke( |
|
2886 |
+ result = runner.invoke( |
|
2918 | 2887 |
# Test parent context navigation by not calling |
2919 | 2888 |
# `cli.derivepassphrase_vault` directly. Used e.g. in |
2920 | 2889 |
# the `--export-as=sh` section to autoconstruct the |
... | ... |
@@ -2923,7 +2892,6 @@ class TestCLI: |
2923 | 2892 |
['vault', '--export', '-', *export_options], |
2924 | 2893 |
catch_exceptions=False, |
2925 | 2894 |
) |
2926 |
- result = tests.ReadableResult.parse(result_) |
|
2927 | 2895 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
2928 | 2896 |
|
2929 | 2897 |
@Parametrize.EXPORT_FORMAT_OPTIONS |
... | ... |
@@ -2932,7 +2900,7 @@ class TestCLI: |
2932 | 2900 |
export_options: list[str], |
2933 | 2901 |
) -> None: |
2934 | 2902 |
"""Exporting an invalid config fails.""" |
2935 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2903 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2936 | 2904 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2937 | 2905 |
# with-statements. |
2938 | 2906 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2945,13 +2913,12 @@ class TestCLI: |
2945 | 2913 |
vault_config={}, |
2946 | 2914 |
) |
2947 | 2915 |
) |
2948 |
- result_ = runner.invoke( |
|
2916 |
+ result = runner.invoke( |
|
2949 | 2917 |
cli.derivepassphrase_vault, |
2950 | 2918 |
['--export', '-', *export_options], |
2951 | 2919 |
input='null', |
2952 | 2920 |
catch_exceptions=False, |
2953 | 2921 |
) |
2954 |
- result = tests.ReadableResult.parse(result_) |
|
2955 | 2922 |
assert result.error_exit(error='Cannot load vault settings:'), ( |
2956 | 2923 |
'expected error exit and known error message' |
2957 | 2924 |
) |
... | ... |
@@ -2962,7 +2929,7 @@ class TestCLI: |
2962 | 2929 |
export_options: list[str], |
2963 | 2930 |
) -> None: |
2964 | 2931 |
"""Exporting an invalid config fails.""" |
2965 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2932 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2966 | 2933 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2967 | 2934 |
# with-statements. |
2968 | 2935 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -2977,13 +2944,12 @@ class TestCLI: |
2977 | 2944 |
config_file = cli_helpers.config_filename(subsystem='vault') |
2978 | 2945 |
config_file.unlink(missing_ok=True) |
2979 | 2946 |
config_file.mkdir(parents=True, exist_ok=True) |
2980 |
- result_ = runner.invoke( |
|
2947 |
+ result = runner.invoke( |
|
2981 | 2948 |
cli.derivepassphrase_vault, |
2982 | 2949 |
['--export', '-', *export_options], |
2983 | 2950 |
input='null', |
2984 | 2951 |
catch_exceptions=False, |
2985 | 2952 |
) |
2986 |
- result = tests.ReadableResult.parse(result_) |
|
2987 | 2953 |
assert result.error_exit(error='Cannot load vault settings:'), ( |
2988 | 2954 |
'expected error exit and known error message' |
2989 | 2955 |
) |
... | ... |
@@ -2994,7 +2960,7 @@ class TestCLI: |
2994 | 2960 |
export_options: list[str], |
2995 | 2961 |
) -> None: |
2996 | 2962 |
"""Exporting an invalid config fails.""" |
2997 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2963 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
2998 | 2964 |
# TODO(the-13th-letter): Rewrite using parenthesized |
2999 | 2965 |
# with-statements. |
3000 | 2966 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3007,13 +2973,12 @@ class TestCLI: |
3007 | 2973 |
) |
3008 | 2974 |
) |
3009 | 2975 |
dname = cli_helpers.config_filename(subsystem=None) |
3010 |
- result_ = runner.invoke( |
|
2976 |
+ result = runner.invoke( |
|
3011 | 2977 |
cli.derivepassphrase_vault, |
3012 | 2978 |
['--export', os.fsdecode(dname), *export_options], |
3013 | 2979 |
input='null', |
3014 | 2980 |
catch_exceptions=False, |
3015 | 2981 |
) |
3016 |
- result = tests.ReadableResult.parse(result_) |
|
3017 | 2982 |
assert result.error_exit(error='Cannot export vault settings:'), ( |
3018 | 2983 |
'expected error exit and known error message' |
3019 | 2984 |
) |
... | ... |
@@ -3024,7 +2989,7 @@ class TestCLI: |
3024 | 2989 |
export_options: list[str], |
3025 | 2990 |
) -> None: |
3026 | 2991 |
"""Exporting an invalid config fails.""" |
3027 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
2992 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3028 | 2993 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3029 | 2994 |
# with-statements. |
3030 | 2995 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3040,13 +3005,12 @@ class TestCLI: |
3040 | 3005 |
with contextlib.suppress(FileNotFoundError): |
3041 | 3006 |
shutil.rmtree(config_dir) |
3042 | 3007 |
config_dir.write_text('Obstruction!!\n') |
3043 |
- result_ = runner.invoke( |
|
3008 |
+ result = runner.invoke( |
|
3044 | 3009 |
cli.derivepassphrase_vault, |
3045 | 3010 |
['--export', '-', *export_options], |
3046 | 3011 |
input='null', |
3047 | 3012 |
catch_exceptions=False, |
3048 | 3013 |
) |
3049 |
- result = tests.ReadableResult.parse(result_) |
|
3050 | 3014 |
assert result.error_exit( |
3051 | 3015 |
error='Cannot load vault settings:' |
3052 | 3016 |
) or result.error_exit(error='Cannot load user config:'), ( |
... | ... |
@@ -3083,7 +3047,7 @@ class TestCLI: |
3083 | 3047 |
if notes_placement == 'before' |
3084 | 3048 |
else f'{result_phrase}\n\n{notes}\n\n' |
3085 | 3049 |
) |
3086 |
- runner = click.testing.CliRunner(mix_stderr=True) |
|
3050 |
+ runner = tests.CliRunner(mix_stderr=True) |
|
3087 | 3051 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3088 | 3052 |
# with-statements. |
3089 | 3053 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3096,12 +3060,11 @@ class TestCLI: |
3096 | 3060 |
vault_config=vault_config, |
3097 | 3061 |
) |
3098 | 3062 |
) |
3099 |
- result_ = runner.invoke( |
|
3063 |
+ result = runner.invoke( |
|
3100 | 3064 |
cli.derivepassphrase_vault, |
3101 | 3065 |
[*placement_args, '--', DUMMY_SERVICE], |
3102 | 3066 |
catch_exceptions=False, |
3103 | 3067 |
) |
3104 |
- result = tests.ReadableResult.parse(result_) |
|
3105 | 3068 |
assert result.clean_exit(output=expected), 'expected clean exit' |
3106 | 3069 |
|
3107 | 3070 |
@Parametrize.MODERN_EDITOR_INTERFACE |
... | ... |
@@ -3137,7 +3100,7 @@ class TestCLI: |
3137 | 3100 |
""" |
3138 | 3101 |
# Reset caplog between hypothesis runs. |
3139 | 3102 |
caplog.clear() |
3140 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3103 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3141 | 3104 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3142 | 3105 |
# with-statements. |
3143 | 3106 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3161,7 +3124,7 @@ class TestCLI: |
3161 | 3124 |
encoding='UTF-8', |
3162 | 3125 |
) |
3163 | 3126 |
monkeypatch.setattr(click, 'edit', lambda *_a, **_kw: edit_result) |
3164 |
- result_ = runner.invoke( |
|
3127 |
+ result = runner.invoke( |
|
3165 | 3128 |
cli.derivepassphrase_vault, |
3166 | 3129 |
[ |
3167 | 3130 |
'--config', |
... | ... |
@@ -3174,7 +3137,6 @@ class TestCLI: |
3174 | 3137 |
], |
3175 | 3138 |
catch_exceptions=False, |
3176 | 3139 |
) |
3177 |
- result = tests.ReadableResult.parse(result_) |
|
3178 | 3140 |
assert result.clean_exit(), 'expected clean exit' |
3179 | 3141 |
assert all(map(is_warning_line, result.stderr.splitlines(True))) |
3180 | 3142 |
assert modern_editor_interface or tests.warning_emitted( |
... | ... |
@@ -3228,7 +3190,7 @@ class TestCLI: |
3228 | 3190 |
return ' ' + notes.strip() + '\n\n\n\n\n\n' |
3229 | 3191 |
|
3230 | 3192 |
edit_funcs = {'empty': empty, 'space': space} |
3231 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3193 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3232 | 3194 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3233 | 3195 |
# with-statements. |
3234 | 3196 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3252,7 +3214,7 @@ class TestCLI: |
3252 | 3214 |
encoding='UTF-8', |
3253 | 3215 |
) |
3254 | 3216 |
monkeypatch.setattr(click, 'edit', edit_funcs[edit_func_name]) |
3255 |
- result_ = runner.invoke( |
|
3217 |
+ result = runner.invoke( |
|
3256 | 3218 |
cli.derivepassphrase_vault, |
3257 | 3219 |
[ |
3258 | 3220 |
'--config', |
... | ... |
@@ -3265,7 +3227,6 @@ class TestCLI: |
3265 | 3227 |
], |
3266 | 3228 |
catch_exceptions=False, |
3267 | 3229 |
) |
3268 |
- result = tests.ReadableResult.parse(result_) |
|
3269 | 3230 |
assert result.clean_exit(empty_stderr=True) or result.error_exit( |
3270 | 3231 |
error='the user aborted the request' |
3271 | 3232 |
), 'expected clean exit' |
... | ... |
@@ -3318,7 +3279,7 @@ class TestCLI: |
3318 | 3279 |
hypothesis.assume(str(notes_marker) not in notes.strip()) |
3319 | 3280 |
# Reset caplog between hypothesis runs. |
3320 | 3281 |
caplog.clear() |
3321 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3282 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3322 | 3283 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3323 | 3284 |
# with-statements. |
3324 | 3285 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3342,7 +3303,7 @@ class TestCLI: |
3342 | 3303 |
encoding='UTF-8', |
3343 | 3304 |
) |
3344 | 3305 |
monkeypatch.setattr(click, 'edit', lambda *_a, **_kw: notes) |
3345 |
- result_ = runner.invoke( |
|
3306 |
+ result = runner.invoke( |
|
3346 | 3307 |
cli.derivepassphrase_vault, |
3347 | 3308 |
[ |
3348 | 3309 |
'--config', |
... | ... |
@@ -3355,7 +3316,6 @@ class TestCLI: |
3355 | 3316 |
], |
3356 | 3317 |
catch_exceptions=False, |
3357 | 3318 |
) |
3358 |
- result = tests.ReadableResult.parse(result_) |
|
3359 | 3319 |
assert result.clean_exit(), 'expected clean exit' |
3360 | 3320 |
assert not result.stderr or all( |
3361 | 3321 |
map(is_warning_line, result.stderr.splitlines(True)) |
... | ... |
@@ -3396,7 +3356,7 @@ class TestCLI: |
3396 | 3356 |
Aborting is only supported with the modern editor interface. |
3397 | 3357 |
|
3398 | 3358 |
""" |
3399 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3359 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3400 | 3360 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3401 | 3361 |
# with-statements. |
3402 | 3362 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3413,7 +3373,7 @@ class TestCLI: |
3413 | 3373 |
) |
3414 | 3374 |
) |
3415 | 3375 |
monkeypatch.setattr(click, 'edit', lambda *_a, **_kw: '') |
3416 |
- result_ = runner.invoke( |
|
3376 |
+ result = runner.invoke( |
|
3417 | 3377 |
cli.derivepassphrase_vault, |
3418 | 3378 |
[ |
3419 | 3379 |
'--config', |
... | ... |
@@ -3424,7 +3384,6 @@ class TestCLI: |
3424 | 3384 |
], |
3425 | 3385 |
catch_exceptions=False, |
3426 | 3386 |
) |
3427 |
- result = tests.ReadableResult.parse(result_) |
|
3428 | 3387 |
assert result.error_exit(error='the user aborted the request'), ( |
3429 | 3388 |
'expected known error message' |
3430 | 3389 |
) |
... | ... |
@@ -3445,7 +3404,7 @@ class TestCLI: |
3445 | 3404 |
Aborting is only supported with the modern editor interface. |
3446 | 3405 |
|
3447 | 3406 |
""" |
3448 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3407 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3449 | 3408 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3450 | 3409 |
# with-statements. |
3451 | 3410 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3462,7 +3421,7 @@ class TestCLI: |
3462 | 3421 |
) |
3463 | 3422 |
) |
3464 | 3423 |
monkeypatch.setattr(click, 'edit', lambda *_a, **_kw: '') |
3465 |
- result_ = runner.invoke( |
|
3424 |
+ result = runner.invoke( |
|
3466 | 3425 |
cli.derivepassphrase_vault, |
3467 | 3426 |
[ |
3468 | 3427 |
'--config', |
... | ... |
@@ -3473,7 +3432,6 @@ class TestCLI: |
3473 | 3432 |
], |
3474 | 3433 |
catch_exceptions=False, |
3475 | 3434 |
) |
3476 |
- result = tests.ReadableResult.parse(result_) |
|
3477 | 3435 |
assert result.error_exit(error='the user aborted the request'), ( |
3478 | 3436 |
'expected known error message' |
3479 | 3437 |
) |
... | ... |
@@ -3517,7 +3475,7 @@ class TestCLI: |
3517 | 3475 |
} |
3518 | 3476 |
# Reset caplog between hypothesis runs. |
3519 | 3477 |
caplog.clear() |
3520 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3478 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3521 | 3479 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3522 | 3480 |
# with-statements. |
3523 | 3481 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3543,7 +3501,7 @@ class TestCLI: |
3543 | 3501 |
encoding='UTF-8', |
3544 | 3502 |
) |
3545 | 3503 |
monkeypatch.setattr(click, 'edit', raiser) |
3546 |
- result_ = runner.invoke( |
|
3504 |
+ result = runner.invoke( |
|
3547 | 3505 |
cli.derivepassphrase_vault, |
3548 | 3506 |
[ |
3549 | 3507 |
'--notes', |
... | ... |
@@ -3555,7 +3513,6 @@ class TestCLI: |
3555 | 3513 |
], |
3556 | 3514 |
catch_exceptions=False, |
3557 | 3515 |
) |
3558 |
- result = tests.ReadableResult.parse(result_) |
|
3559 | 3516 |
assert result.clean_exit( |
3560 | 3517 |
output=DUMMY_RESULT_PASSPHRASE.decode('ascii') |
3561 | 3518 |
), 'expected clean exit' |
... | ... |
@@ -3595,7 +3552,7 @@ class TestCLI: |
3595 | 3552 |
the config more readable. |
3596 | 3553 |
|
3597 | 3554 |
""" |
3598 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3555 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3599 | 3556 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3600 | 3557 |
# with-statements. |
3601 | 3558 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3611,13 +3568,12 @@ class TestCLI: |
3611 | 3568 |
monkeypatch.setattr( |
3612 | 3569 |
cli_helpers, 'get_suitable_ssh_keys', tests.suitable_ssh_keys |
3613 | 3570 |
) |
3614 |
- result_ = runner.invoke( |
|
3571 |
+ result = runner.invoke( |
|
3615 | 3572 |
cli.derivepassphrase_vault, |
3616 | 3573 |
['--config', *command_line], |
3617 | 3574 |
catch_exceptions=False, |
3618 | 3575 |
input=input, |
3619 | 3576 |
) |
3620 |
- result = tests.ReadableResult.parse(result_) |
|
3621 | 3577 |
assert result.clean_exit(), 'expected clean exit' |
3622 | 3578 |
config_txt = cli_helpers.config_filename( |
3623 | 3579 |
subsystem='vault' |
... | ... |
@@ -3636,7 +3592,7 @@ class TestCLI: |
3636 | 3592 |
err_text: str, |
3637 | 3593 |
) -> None: |
3638 | 3594 |
"""Storing invalid settings via `--config` fails.""" |
3639 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3595 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3640 | 3596 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3641 | 3597 |
# with-statements. |
3642 | 3598 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3652,13 +3608,12 @@ class TestCLI: |
3652 | 3608 |
monkeypatch.setattr( |
3653 | 3609 |
cli_helpers, 'get_suitable_ssh_keys', tests.suitable_ssh_keys |
3654 | 3610 |
) |
3655 |
- result_ = runner.invoke( |
|
3611 |
+ result = runner.invoke( |
|
3656 | 3612 |
cli.derivepassphrase_vault, |
3657 | 3613 |
['--config', *command_line], |
3658 | 3614 |
catch_exceptions=False, |
3659 | 3615 |
input=input, |
3660 | 3616 |
) |
3661 |
- result = tests.ReadableResult.parse(result_) |
|
3662 | 3617 |
assert result.error_exit(error=err_text), ( |
3663 | 3618 |
'expected error exit and known error message' |
3664 | 3619 |
) |
... | ... |
@@ -3667,7 +3622,7 @@ class TestCLI: |
3667 | 3622 |
self, |
3668 | 3623 |
) -> None: |
3669 | 3624 |
"""Not selecting an SSH key during `--config --key` fails.""" |
3670 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3625 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3671 | 3626 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3672 | 3627 |
# with-statements. |
3673 | 3628 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3686,12 +3641,11 @@ class TestCLI: |
3686 | 3641 |
raise RuntimeError(custom_error) |
3687 | 3642 |
|
3688 | 3643 |
monkeypatch.setattr(cli_helpers, 'select_ssh_key', raiser) |
3689 |
- result_ = runner.invoke( |
|
3644 |
+ result = runner.invoke( |
|
3690 | 3645 |
cli.derivepassphrase_vault, |
3691 | 3646 |
['--key', '--config'], |
3692 | 3647 |
catch_exceptions=False, |
3693 | 3648 |
) |
3694 |
- result = tests.ReadableResult.parse(result_) |
|
3695 | 3649 |
assert result.error_exit(error=custom_error), ( |
3696 | 3650 |
'expected error exit and known error message' |
3697 | 3651 |
) |
... | ... |
@@ -3702,7 +3656,7 @@ class TestCLI: |
3702 | 3656 |
) -> None: |
3703 | 3657 |
"""Not running an SSH agent during `--config --key` fails.""" |
3704 | 3658 |
del skip_if_no_af_unix_support |
3705 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3659 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3706 | 3660 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3707 | 3661 |
# with-statements. |
3708 | 3662 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3716,12 +3670,11 @@ class TestCLI: |
3716 | 3670 |
) |
3717 | 3671 |
) |
3718 | 3672 |
monkeypatch.delenv('SSH_AUTH_SOCK', raising=False) |
3719 |
- result_ = runner.invoke( |
|
3673 |
+ result = runner.invoke( |
|
3720 | 3674 |
cli.derivepassphrase_vault, |
3721 | 3675 |
['--key', '--config'], |
3722 | 3676 |
catch_exceptions=False, |
3723 | 3677 |
) |
3724 |
- result = tests.ReadableResult.parse(result_) |
|
3725 | 3678 |
assert result.error_exit(error='Cannot find any running SSH agent'), ( |
3726 | 3679 |
'expected error exit and known error message' |
3727 | 3680 |
) |
... | ... |
@@ -3730,7 +3683,7 @@ class TestCLI: |
3730 | 3683 |
self, |
3731 | 3684 |
) -> None: |
3732 | 3685 |
"""Not running a reachable SSH agent during `--config --key` fails.""" |
3733 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3686 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3734 | 3687 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3735 | 3688 |
# with-statements. |
3736 | 3689 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3745,12 +3698,11 @@ class TestCLI: |
3745 | 3698 |
) |
3746 | 3699 |
cwd = pathlib.Path.cwd().resolve() |
3747 | 3700 |
monkeypatch.setenv('SSH_AUTH_SOCK', str(cwd)) |
3748 |
- result_ = runner.invoke( |
|
3701 |
+ result = runner.invoke( |
|
3749 | 3702 |
cli.derivepassphrase_vault, |
3750 | 3703 |
['--key', '--config'], |
3751 | 3704 |
catch_exceptions=False, |
3752 | 3705 |
) |
3753 |
- result = tests.ReadableResult.parse(result_) |
|
3754 | 3706 |
assert result.error_exit(error='Cannot connect to the SSH agent'), ( |
3755 | 3707 |
'expected error exit and known error message' |
3756 | 3708 |
) |
... | ... |
@@ -3761,7 +3713,7 @@ class TestCLI: |
3761 | 3713 |
try_race_free_implementation: bool, |
3762 | 3714 |
) -> None: |
3763 | 3715 |
"""Using a read-only configuration file with `--config` fails.""" |
3764 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3716 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3765 | 3717 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3766 | 3718 |
# with-statements. |
3767 | 3719 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3778,12 +3730,11 @@ class TestCLI: |
3778 | 3730 |
cli_helpers.config_filename(subsystem='vault'), |
3779 | 3731 |
try_race_free_implementation=try_race_free_implementation, |
3780 | 3732 |
) |
3781 |
- result_ = runner.invoke( |
|
3733 |
+ result = runner.invoke( |
|
3782 | 3734 |
cli.derivepassphrase_vault, |
3783 | 3735 |
['--config', '--length=15', '--', DUMMY_SERVICE], |
3784 | 3736 |
catch_exceptions=False, |
3785 | 3737 |
) |
3786 |
- result = tests.ReadableResult.parse(result_) |
|
3787 | 3738 |
assert result.error_exit(error='Cannot store vault settings:'), ( |
3788 | 3739 |
'expected error exit and known error message' |
3789 | 3740 |
) |
... | ... |
@@ -3792,7 +3743,7 @@ class TestCLI: |
3792 | 3743 |
self, |
3793 | 3744 |
) -> None: |
3794 | 3745 |
"""OS-erroring with `--config` fails.""" |
3795 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3746 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3796 | 3747 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3797 | 3748 |
# with-statements. |
3798 | 3749 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3812,12 +3763,11 @@ class TestCLI: |
3812 | 3763 |
raise RuntimeError(custom_error) |
3813 | 3764 |
|
3814 | 3765 |
monkeypatch.setattr(cli_helpers, 'save_config', raiser) |
3815 |
- result_ = runner.invoke( |
|
3766 |
+ result = runner.invoke( |
|
3816 | 3767 |
cli.derivepassphrase_vault, |
3817 | 3768 |
['--config', '--length=15', '--', DUMMY_SERVICE], |
3818 | 3769 |
catch_exceptions=False, |
3819 | 3770 |
) |
3820 |
- result = tests.ReadableResult.parse(result_) |
|
3821 | 3771 |
assert result.error_exit(error=custom_error), ( |
3822 | 3772 |
'expected error exit and known error message' |
3823 | 3773 |
) |
... | ... |
@@ -3826,7 +3776,7 @@ class TestCLI: |
3826 | 3776 |
self, |
3827 | 3777 |
) -> None: |
3828 | 3778 |
"""Issuing conflicting settings to `--config` fails.""" |
3829 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3779 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3830 | 3780 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3831 | 3781 |
# with-statements. |
3832 | 3782 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3839,7 +3789,7 @@ class TestCLI: |
3839 | 3789 |
vault_config={'global': {'phrase': 'abc'}, 'services': {}}, |
3840 | 3790 |
) |
3841 | 3791 |
) |
3842 |
- result_ = runner.invoke( |
|
3792 |
+ result = runner.invoke( |
|
3843 | 3793 |
cli.derivepassphrase_vault, |
3844 | 3794 |
[ |
3845 | 3795 |
'--config', |
... | ... |
@@ -3850,7 +3800,6 @@ class TestCLI: |
3850 | 3800 |
], |
3851 | 3801 |
catch_exceptions=False, |
3852 | 3802 |
) |
3853 |
- result = tests.ReadableResult.parse(result_) |
|
3854 | 3803 |
assert result.error_exit( |
3855 | 3804 |
error='Attempted to unset and set --length at the same time.' |
3856 | 3805 |
), 'expected error exit and known error message' |
... | ... |
@@ -3861,7 +3810,7 @@ class TestCLI: |
3861 | 3810 |
) -> None: |
3862 | 3811 |
"""Not holding any SSH keys during `--config --key` fails.""" |
3863 | 3812 |
del running_ssh_agent |
3864 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3813 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3865 | 3814 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3866 | 3815 |
# with-statements. |
3867 | 3816 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3882,12 +3831,11 @@ class TestCLI: |
3882 | 3831 |
return [] |
3883 | 3832 |
|
3884 | 3833 |
monkeypatch.setattr(ssh_agent.SSHAgentClient, 'list_keys', func) |
3885 |
- result_ = runner.invoke( |
|
3834 |
+ result = runner.invoke( |
|
3886 | 3835 |
cli.derivepassphrase_vault, |
3887 | 3836 |
['--key', '--config'], |
3888 | 3837 |
catch_exceptions=False, |
3889 | 3838 |
) |
3890 |
- result = tests.ReadableResult.parse(result_) |
|
3891 | 3839 |
assert result.error_exit(error='no keys suitable'), ( |
3892 | 3840 |
'expected error exit and known error message' |
3893 | 3841 |
) |
... | ... |
@@ -3898,7 +3846,7 @@ class TestCLI: |
3898 | 3846 |
) -> None: |
3899 | 3847 |
"""The SSH agent erroring during `--config --key` fails.""" |
3900 | 3848 |
del running_ssh_agent |
3901 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3849 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3902 | 3850 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3903 | 3851 |
# with-statements. |
3904 | 3852 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3916,12 +3864,11 @@ class TestCLI: |
3916 | 3864 |
raise ssh_agent.TrailingDataError() |
3917 | 3865 |
|
3918 | 3866 |
monkeypatch.setattr(ssh_agent.SSHAgentClient, 'list_keys', raiser) |
3919 |
- result_ = runner.invoke( |
|
3867 |
+ result = runner.invoke( |
|
3920 | 3868 |
cli.derivepassphrase_vault, |
3921 | 3869 |
['--key', '--config'], |
3922 | 3870 |
catch_exceptions=False, |
3923 | 3871 |
) |
3924 |
- result = tests.ReadableResult.parse(result_) |
|
3925 | 3872 |
assert result.error_exit( |
3926 | 3873 |
error='violates the communication protocol.' |
3927 | 3874 |
), 'expected error exit and known error message' |
... | ... |
@@ -3932,7 +3879,7 @@ class TestCLI: |
3932 | 3879 |
) -> None: |
3933 | 3880 |
"""The SSH agent refusing during `--config --key` fails.""" |
3934 | 3881 |
del running_ssh_agent |
3935 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3882 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3936 | 3883 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3937 | 3884 |
# with-statements. |
3938 | 3885 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3952,19 +3899,18 @@ class TestCLI: |
3952 | 3899 |
) |
3953 | 3900 |
|
3954 | 3901 |
monkeypatch.setattr(ssh_agent.SSHAgentClient, 'list_keys', func) |
3955 |
- result_ = runner.invoke( |
|
3902 |
+ result = runner.invoke( |
|
3956 | 3903 |
cli.derivepassphrase_vault, |
3957 | 3904 |
['--key', '--config'], |
3958 | 3905 |
catch_exceptions=False, |
3959 | 3906 |
) |
3960 |
- result = tests.ReadableResult.parse(result_) |
|
3961 | 3907 |
assert result.error_exit(error='refused to'), ( |
3962 | 3908 |
'expected error exit and known error message' |
3963 | 3909 |
) |
3964 | 3910 |
|
3965 | 3911 |
def test_226_no_arguments(self) -> None: |
3966 | 3912 |
"""Calling `derivepassphrase vault` without any arguments fails.""" |
3967 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3913 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3968 | 3914 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3969 | 3915 |
# with-statements. |
3970 | 3916 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -3976,10 +3922,9 @@ class TestCLI: |
3976 | 3922 |
runner=runner, |
3977 | 3923 |
) |
3978 | 3924 |
) |
3979 |
- result_ = runner.invoke( |
|
3925 |
+ result = runner.invoke( |
|
3980 | 3926 |
cli.derivepassphrase_vault, [], catch_exceptions=False |
3981 | 3927 |
) |
3982 |
- result = tests.ReadableResult.parse(result_) |
|
3983 | 3928 |
assert result.error_exit( |
3984 | 3929 |
error='Deriving a passphrase requires a SERVICE' |
3985 | 3930 |
), 'expected error exit and known error message' |
... | ... |
@@ -3988,7 +3933,7 @@ class TestCLI: |
3988 | 3933 |
self, |
3989 | 3934 |
) -> None: |
3990 | 3935 |
"""Deriving a passphrase without a passphrase or key fails.""" |
3991 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3936 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
3992 | 3937 |
# TODO(the-13th-letter): Rewrite using parenthesized |
3993 | 3938 |
# with-statements. |
3994 | 3939 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4000,12 +3945,11 @@ class TestCLI: |
4000 | 3945 |
runner=runner, |
4001 | 3946 |
) |
4002 | 3947 |
) |
4003 |
- result_ = runner.invoke( |
|
3948 |
+ result = runner.invoke( |
|
4004 | 3949 |
cli.derivepassphrase_vault, |
4005 | 3950 |
['--', DUMMY_SERVICE], |
4006 | 3951 |
catch_exceptions=False, |
4007 | 3952 |
) |
4008 |
- result = tests.ReadableResult.parse(result_) |
|
4009 | 3953 |
assert result.error_exit(error='No passphrase or key was given'), ( |
4010 | 3954 |
'expected error exit and known error message' |
4011 | 3955 |
) |
... | ... |
@@ -4020,7 +3964,7 @@ class TestCLI: |
4020 | 3964 |
[issue #6]: https://github.com/the-13th-letter/derivepassphrase/issues/6 |
4021 | 3965 |
|
4022 | 3966 |
""" |
4023 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
3967 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4024 | 3968 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4025 | 3969 |
# with-statements. |
4026 | 3970 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4034,13 +3978,12 @@ class TestCLI: |
4034 | 3978 |
) |
4035 | 3979 |
with contextlib.suppress(FileNotFoundError): |
4036 | 3980 |
shutil.rmtree(cli_helpers.config_filename(subsystem=None)) |
4037 |
- result_ = runner.invoke( |
|
3981 |
+ result = runner.invoke( |
|
4038 | 3982 |
cli.derivepassphrase_vault, |
4039 | 3983 |
['--config', '-p'], |
4040 | 3984 |
catch_exceptions=False, |
4041 | 3985 |
input='abc\n', |
4042 | 3986 |
) |
4043 |
- result = tests.ReadableResult.parse(result_) |
|
4044 | 3987 |
assert result.clean_exit(), 'expected clean exit' |
4045 | 3988 |
assert result.stderr == 'Passphrase:', ( |
4046 | 3989 |
'program unexpectedly failed?!' |
... | ... |
@@ -4067,7 +4010,7 @@ class TestCLI: |
4067 | 4010 |
[issue #6]: https://github.com/the-13th-letter/derivepassphrase/issues/6 |
4068 | 4011 |
|
4069 | 4012 |
""" |
4070 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4013 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4071 | 4014 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4072 | 4015 |
# with-statements. |
4073 | 4016 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4092,13 +4035,12 @@ class TestCLI: |
4092 | 4035 |
monkeypatch.setattr( |
4093 | 4036 |
cli_helpers, 'save_config', obstruct_config_saving |
4094 | 4037 |
) |
4095 |
- result_ = runner.invoke( |
|
4038 |
+ result = runner.invoke( |
|
4096 | 4039 |
cli.derivepassphrase_vault, |
4097 | 4040 |
['--config', '-p'], |
4098 | 4041 |
catch_exceptions=False, |
4099 | 4042 |
input='abc\n', |
4100 | 4043 |
) |
4101 |
- result = tests.ReadableResult.parse(result_) |
|
4102 | 4044 |
assert result.error_exit(error='Cannot store vault settings:'), ( |
4103 | 4045 |
'expected error exit and known error message' |
4104 | 4046 |
) |
... | ... |
@@ -4107,7 +4049,7 @@ class TestCLI: |
4107 | 4049 |
self, |
4108 | 4050 |
) -> None: |
4109 | 4051 |
"""Storing the configuration reacts even to weird errors.""" |
4110 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4052 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4111 | 4053 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4112 | 4054 |
# with-statements. |
4113 | 4055 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4126,13 +4068,12 @@ class TestCLI: |
4126 | 4068 |
raise RuntimeError(custom_error) |
4127 | 4069 |
|
4128 | 4070 |
monkeypatch.setattr(cli_helpers, 'save_config', raiser) |
4129 |
- result_ = runner.invoke( |
|
4071 |
+ result = runner.invoke( |
|
4130 | 4072 |
cli.derivepassphrase_vault, |
4131 | 4073 |
['--config', '-p'], |
4132 | 4074 |
catch_exceptions=False, |
4133 | 4075 |
input='abc\n', |
4134 | 4076 |
) |
4135 |
- result = tests.ReadableResult.parse(result_) |
|
4136 | 4077 |
assert result.error_exit(error=custom_error), ( |
4137 | 4078 |
'expected error exit and known error message' |
4138 | 4079 |
) |
... | ... |
@@ -4147,7 +4088,7 @@ class TestCLI: |
4147 | 4088 |
warning_message: str, |
4148 | 4089 |
) -> None: |
4149 | 4090 |
"""Using unnormalized Unicode passphrases warns.""" |
4150 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4091 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4151 | 4092 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4152 | 4093 |
# with-statements. |
4153 | 4094 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4165,13 +4106,12 @@ class TestCLI: |
4165 | 4106 |
main_config_str=main_config, |
4166 | 4107 |
) |
4167 | 4108 |
) |
4168 |
- result_ = runner.invoke( |
|
4109 |
+ result = runner.invoke( |
|
4169 | 4110 |
cli.derivepassphrase_vault, |
4170 | 4111 |
['--debug', *command_line], |
4171 | 4112 |
catch_exceptions=False, |
4172 | 4113 |
input=input, |
4173 | 4114 |
) |
4174 |
- result = tests.ReadableResult.parse(result_) |
|
4175 | 4115 |
assert result.clean_exit(), 'expected clean exit' |
4176 | 4116 |
assert tests.warning_emitted(warning_message, caplog.record_tuples), ( |
4177 | 4117 |
'expected known warning message in stderr' |
... | ... |
@@ -4186,7 +4126,7 @@ class TestCLI: |
4186 | 4126 |
error_message: str, |
4187 | 4127 |
) -> None: |
4188 | 4128 |
"""Using unknown Unicode normalization forms fails.""" |
4189 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4129 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4190 | 4130 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4191 | 4131 |
# with-statements. |
4192 | 4132 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4204,13 +4144,12 @@ class TestCLI: |
4204 | 4144 |
main_config_str=main_config, |
4205 | 4145 |
) |
4206 | 4146 |
) |
4207 |
- result_ = runner.invoke( |
|
4147 |
+ result = runner.invoke( |
|
4208 | 4148 |
cli.derivepassphrase_vault, |
4209 | 4149 |
command_line, |
4210 | 4150 |
catch_exceptions=False, |
4211 | 4151 |
input=input, |
4212 | 4152 |
) |
4213 |
- result = tests.ReadableResult.parse(result_) |
|
4214 | 4153 |
assert result.error_exit( |
4215 | 4154 |
error='The user configuration file is invalid.' |
4216 | 4155 |
), 'expected error exit and known error message' |
... | ... |
@@ -4224,7 +4163,7 @@ class TestCLI: |
4224 | 4163 |
command_line: list[str], |
4225 | 4164 |
) -> None: |
4226 | 4165 |
"""Using unknown Unicode normalization forms in the config fails.""" |
4227 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4166 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4228 | 4167 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4229 | 4168 |
# with-statements. |
4230 | 4169 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4244,13 +4183,12 @@ class TestCLI: |
4244 | 4183 |
), |
4245 | 4184 |
) |
4246 | 4185 |
) |
4247 |
- result_ = runner.invoke( |
|
4186 |
+ result = runner.invoke( |
|
4248 | 4187 |
cli.derivepassphrase_vault, |
4249 | 4188 |
command_line, |
4250 | 4189 |
input=DUMMY_PASSPHRASE, |
4251 | 4190 |
catch_exceptions=False, |
4252 | 4191 |
) |
4253 |
- result = tests.ReadableResult.parse(result_) |
|
4254 | 4192 |
assert result.error_exit( |
4255 | 4193 |
error='The user configuration file is invalid.' |
4256 | 4194 |
), 'expected error exit and known error message' |
... | ... |
@@ -4265,7 +4203,7 @@ class TestCLI: |
4265 | 4203 |
self, |
4266 | 4204 |
) -> None: |
4267 | 4205 |
"""Loading a user configuration file in an invalid format fails.""" |
4268 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4206 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4269 | 4207 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4270 | 4208 |
# with-statements. |
4271 | 4209 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4279,13 +4217,12 @@ class TestCLI: |
4279 | 4217 |
main_config_str='This file is not valid TOML.\n', |
4280 | 4218 |
) |
4281 | 4219 |
) |
4282 |
- result_ = runner.invoke( |
|
4220 |
+ result = runner.invoke( |
|
4283 | 4221 |
cli.derivepassphrase_vault, |
4284 | 4222 |
['--phrase', '--', DUMMY_SERVICE], |
4285 | 4223 |
input=DUMMY_PASSPHRASE, |
4286 | 4224 |
catch_exceptions=False, |
4287 | 4225 |
) |
4288 |
- result = tests.ReadableResult.parse(result_) |
|
4289 | 4226 |
assert result.error_exit(error='Cannot load user config:'), ( |
4290 | 4227 |
'expected error exit and known error message' |
4291 | 4228 |
) |
... | ... |
@@ -4294,7 +4231,7 @@ class TestCLI: |
4294 | 4231 |
self, |
4295 | 4232 |
) -> None: |
4296 | 4233 |
"""Loading a user configuration file in an invalid format fails.""" |
4297 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4234 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4298 | 4235 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4299 | 4236 |
# with-statements. |
4300 | 4237 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4313,13 +4250,12 @@ class TestCLI: |
4313 | 4250 |
) |
4314 | 4251 |
user_config.unlink() |
4315 | 4252 |
user_config.mkdir(parents=True, exist_ok=True) |
4316 |
- result_ = runner.invoke( |
|
4253 |
+ result = runner.invoke( |
|
4317 | 4254 |
cli.derivepassphrase_vault, |
4318 | 4255 |
['--phrase', '--', DUMMY_SERVICE], |
4319 | 4256 |
input=DUMMY_PASSPHRASE, |
4320 | 4257 |
catch_exceptions=False, |
4321 | 4258 |
) |
4322 |
- result = tests.ReadableResult.parse(result_) |
|
4323 | 4259 |
assert result.error_exit(error='Cannot load user config:'), ( |
4324 | 4260 |
'expected error exit and known error message' |
4325 | 4261 |
) |
... | ... |
@@ -4328,7 +4264,7 @@ class TestCLI: |
4328 | 4264 |
self, |
4329 | 4265 |
) -> None: |
4330 | 4266 |
"""Querying the SSH agent without `AF_UNIX` support fails.""" |
4331 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4267 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4332 | 4268 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4333 | 4269 |
# with-statements. |
4334 | 4270 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4345,12 +4281,11 @@ class TestCLI: |
4345 | 4281 |
'SSH_AUTH_SOCK', "the value doesn't even matter" |
4346 | 4282 |
) |
4347 | 4283 |
monkeypatch.delattr(socket, 'AF_UNIX', raising=False) |
4348 |
- result_ = runner.invoke( |
|
4284 |
+ result = runner.invoke( |
|
4349 | 4285 |
cli.derivepassphrase_vault, |
4350 | 4286 |
['--key', '--config'], |
4351 | 4287 |
catch_exceptions=False, |
4352 | 4288 |
) |
4353 |
- result = tests.ReadableResult.parse(result_) |
|
4354 | 4289 |
assert result.error_exit( |
4355 | 4290 |
error='does not support UNIX domain sockets' |
4356 | 4291 |
), 'expected error exit and known error message' |
... | ... |
@@ -4365,7 +4300,7 @@ class TestCLIUtils: |
4365 | 4300 |
config: Any, |
4366 | 4301 |
) -> None: |
4367 | 4302 |
"""[`cli_helpers.load_config`][] works for valid configurations.""" |
4368 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4303 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4369 | 4304 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4370 | 4305 |
# with-statements. |
4371 | 4306 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4387,7 +4322,7 @@ class TestCLIUtils: |
4387 | 4322 |
self, |
4388 | 4323 |
) -> None: |
4389 | 4324 |
"""[`cli_helpers.save_config`][] fails for bad configurations.""" |
4390 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4325 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4391 | 4326 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4392 | 4327 |
# with-statements. |
4393 | 4328 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4437,9 +4372,8 @@ class TestCLIUtils: |
4437 | 4372 |
click.echo(items[index]) |
4438 | 4373 |
click.echo('(Note: Vikings strictly optional.)') |
4439 | 4374 |
|
4440 |
- runner = click.testing.CliRunner(mix_stderr=True) |
|
4441 |
- result_ = runner.invoke(driver, [], input='9') |
|
4442 |
- result = tests.ReadableResult.parse(result_) |
|
4375 |
+ runner = tests.CliRunner(mix_stderr=True) |
|
4376 |
+ result = runner.invoke(driver, [], input='9') |
|
4443 | 4377 |
assert result.clean_exit( |
4444 | 4378 |
output="""\ |
4445 | 4379 |
Our menu: |
... | ... |
@@ -4458,15 +4392,14 @@ A fine choice: Spam, spam, spam, spam, spam, spam, baked beans, spam, spam, spam |
4458 | 4392 |
(Note: Vikings strictly optional.) |
4459 | 4393 |
""" |
4460 | 4394 |
), 'expected clean exit' |
4461 |
- result_ = runner.invoke( |
|
4395 |
+ result = runner.invoke( |
|
4462 | 4396 |
driver, ['--heading='], input='', catch_exceptions=True |
4463 | 4397 |
) |
4464 |
- result = tests.ReadableResult.parse(result_) |
|
4465 | 4398 |
assert result.error_exit(error=IndexError), ( |
4466 | 4399 |
'expected error exit and known error type' |
4467 | 4400 |
) |
4468 | 4401 |
assert ( |
4469 |
- result.output |
|
4402 |
+ result.stdout |
|
4470 | 4403 |
== """\ |
4471 | 4404 |
[1] Egg and bacon |
4472 | 4405 |
[2] Egg, sausage and bacon |
... | ... |
@@ -4499,11 +4432,10 @@ Your selection? (1-10, leave empty to abort):\x20 |
4499 | 4432 |
else: |
4500 | 4433 |
click.echo('Great!') |
4501 | 4434 |
|
4502 |
- runner = click.testing.CliRunner(mix_stderr=True) |
|
4503 |
- result_ = runner.invoke( |
|
4435 |
+ runner = tests.CliRunner(mix_stderr=True) |
|
4436 |
+ result = runner.invoke( |
|
4504 | 4437 |
driver, ['Will replace with spam. Confirm, y/n?'], input='y' |
4505 | 4438 |
) |
4506 |
- result = tests.ReadableResult.parse(result_) |
|
4507 | 4439 |
assert result.clean_exit( |
4508 | 4440 |
output="""\ |
4509 | 4441 |
[1] baked beans |
... | ... |
@@ -4511,17 +4443,16 @@ Will replace with spam. Confirm, y/n? y |
4511 | 4443 |
Great! |
4512 | 4444 |
""" |
4513 | 4445 |
), 'expected clean exit' |
4514 |
- result_ = runner.invoke( |
|
4446 |
+ result = runner.invoke( |
|
4515 | 4447 |
driver, |
4516 | 4448 |
['Will replace with spam, okay? (Please say "y" or "n".)'], |
4517 | 4449 |
input='', |
4518 | 4450 |
) |
4519 |
- result = tests.ReadableResult.parse(result_) |
|
4520 | 4451 |
assert result.error_exit(error=IndexError), ( |
4521 | 4452 |
'expected error exit and known error type' |
4522 | 4453 |
) |
4523 | 4454 |
assert ( |
4524 |
- result.output |
|
4455 |
+ result.stdout |
|
4525 | 4456 |
== """\ |
4526 | 4457 |
[1] baked beans |
4527 | 4458 |
Will replace with spam, okay? (Please say "y" or "n".):\x20 |
... | ... |
@@ -4693,7 +4624,7 @@ Boo. |
4693 | 4624 |
config, outfile=outfile, prog_name_list=prog_name_list |
4694 | 4625 |
) |
4695 | 4626 |
script = outfile.getvalue() |
4696 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4627 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4697 | 4628 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4698 | 4629 |
# with-statements. |
4699 | 4630 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4706,8 +4637,7 @@ Boo. |
4706 | 4637 |
vault_config={'services': {}}, |
4707 | 4638 |
) |
4708 | 4639 |
) |
4709 |
- for result_ in vault_config_exporter_shell_interpreter(script): |
|
4710 |
- result = tests.ReadableResult.parse(result_) |
|
4640 |
+ for result in vault_config_exporter_shell_interpreter(script): |
|
4711 | 4641 |
assert result.clean_exit() |
4712 | 4642 |
assert cli_helpers.load_config() == config |
4713 | 4643 |
|
... | ... |
@@ -4943,7 +4873,7 @@ Boo. |
4943 | 4873 |
`cli_helpers.get_tempdir` returned the configuration directory. |
4944 | 4874 |
|
4945 | 4875 |
""" |
4946 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4876 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4947 | 4877 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4948 | 4878 |
# with-statements. |
4949 | 4879 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -4980,7 +4910,7 @@ Boo. |
4980 | 4910 |
configuration directory. |
4981 | 4911 |
|
4982 | 4912 |
""" |
4983 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4913 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
4984 | 4914 |
# TODO(the-13th-letter): Rewrite using parenthesized |
4985 | 4915 |
# with-statements. |
4986 | 4916 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5035,7 +4965,7 @@ Boo. |
5035 | 4965 |
) -> None: |
5036 | 4966 |
"""Repeatedly removing the same parts of a configuration works.""" |
5037 | 4967 |
for start_config in [config, result_config]: |
5038 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
4968 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5039 | 4969 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5040 | 4970 |
# with-statements. |
5041 | 4971 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5048,12 +4978,11 @@ Boo. |
5048 | 4978 |
vault_config=start_config, |
5049 | 4979 |
) |
5050 | 4980 |
) |
5051 |
- result_ = runner.invoke( |
|
4981 |
+ result = runner.invoke( |
|
5052 | 4982 |
cli.derivepassphrase_vault, |
5053 | 4983 |
command_line, |
5054 | 4984 |
catch_exceptions=False, |
5055 | 4985 |
) |
5056 |
- result = tests.ReadableResult.parse(result_) |
|
5057 | 4986 |
assert result.clean_exit(empty_stderr=True), ( |
5058 | 4987 |
'expected clean exit' |
5059 | 4988 |
) |
... | ... |
@@ -5220,7 +5149,7 @@ class TestCLITransition: |
5220 | 5149 |
config: Any, |
5221 | 5150 |
) -> None: |
5222 | 5151 |
"""Loading the old settings file works.""" |
5223 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5152 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5224 | 5153 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5225 | 5154 |
# with-statements. |
5226 | 5155 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5243,7 +5172,7 @@ class TestCLITransition: |
5243 | 5172 |
config: Any, |
5244 | 5173 |
) -> None: |
5245 | 5174 |
"""Migrating the old settings file works.""" |
5246 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5175 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5247 | 5176 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5248 | 5177 |
# with-statements. |
5249 | 5178 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5266,7 +5195,7 @@ class TestCLITransition: |
5266 | 5195 |
config: Any, |
5267 | 5196 |
) -> None: |
5268 | 5197 |
"""Migrating the old settings file atop a directory fails.""" |
5269 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5198 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5270 | 5199 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5271 | 5200 |
# with-statements. |
5272 | 5201 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5295,7 +5224,7 @@ class TestCLITransition: |
5295 | 5224 |
config: Any, |
5296 | 5225 |
) -> None: |
5297 | 5226 |
"""Migrating an invalid old settings file fails.""" |
5298 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5227 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5299 | 5228 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5300 | 5229 |
# with-statements. |
5301 | 5230 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5321,7 +5250,7 @@ class TestCLITransition: |
5321 | 5250 |
) -> None: |
5322 | 5251 |
"""Forwarding arguments from "export" to "export vault" works.""" |
5323 | 5252 |
pytest.importorskip('cryptography', minversion='38.0') |
5324 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5253 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5325 | 5254 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5326 | 5255 |
# with-statements. |
5327 | 5256 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5336,11 +5265,10 @@ class TestCLITransition: |
5336 | 5265 |
) |
5337 | 5266 |
) |
5338 | 5267 |
monkeypatch.setenv('VAULT_KEY', tests.VAULT_MASTER_KEY) |
5339 |
- result_ = runner.invoke( |
|
5268 |
+ result = runner.invoke( |
|
5340 | 5269 |
cli.derivepassphrase, |
5341 | 5270 |
['export', 'VAULT_PATH'], |
5342 | 5271 |
) |
5343 |
- result = tests.ReadableResult.parse(result_) |
|
5344 | 5272 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
5345 | 5273 |
assert tests.deprecation_warning_emitted( |
5346 | 5274 |
'A subcommand will be required here in v1.0', caplog.record_tuples |
... | ... |
@@ -5348,7 +5276,7 @@ class TestCLITransition: |
5348 | 5276 |
assert tests.deprecation_warning_emitted( |
5349 | 5277 |
'Defaulting to subcommand "vault"', caplog.record_tuples |
5350 | 5278 |
) |
5351 |
- assert json.loads(result.output) == tests.VAULT_V03_CONFIG_DATA |
|
5279 |
+ assert json.loads(result.stdout) == tests.VAULT_V03_CONFIG_DATA |
|
5352 | 5280 |
|
5353 | 5281 |
def test_201_forward_export_vault_empty_commandline( |
5354 | 5282 |
self, |
... | ... |
@@ -5356,7 +5284,7 @@ class TestCLITransition: |
5356 | 5284 |
) -> None: |
5357 | 5285 |
"""Deferring from "export" to "export vault" works.""" |
5358 | 5286 |
pytest.importorskip('cryptography', minversion='38.0') |
5359 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5287 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5360 | 5288 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5361 | 5289 |
# with-statements. |
5362 | 5290 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5368,11 +5296,10 @@ class TestCLITransition: |
5368 | 5296 |
runner=runner, |
5369 | 5297 |
) |
5370 | 5298 |
) |
5371 |
- result_ = runner.invoke( |
|
5299 |
+ result = runner.invoke( |
|
5372 | 5300 |
cli.derivepassphrase, |
5373 | 5301 |
['export'], |
5374 | 5302 |
) |
5375 |
- result = tests.ReadableResult.parse(result_) |
|
5376 | 5303 |
assert tests.deprecation_warning_emitted( |
5377 | 5304 |
'A subcommand will be required here in v1.0', caplog.record_tuples |
5378 | 5305 |
) |
... | ... |
@@ -5392,7 +5319,7 @@ class TestCLITransition: |
5392 | 5319 |
"""Forwarding arguments from top-level to "vault" works.""" |
5393 | 5320 |
option = f'--{charset_name}' |
5394 | 5321 |
charset = vault.Vault.CHARSETS[charset_name].decode('ascii') |
5395 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5322 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5396 | 5323 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5397 | 5324 |
# with-statements. |
5398 | 5325 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5407,13 +5334,12 @@ class TestCLITransition: |
5407 | 5334 |
monkeypatch.setattr( |
5408 | 5335 |
cli_helpers, 'prompt_for_passphrase', tests.auto_prompt |
5409 | 5336 |
) |
5410 |
- result_ = runner.invoke( |
|
5337 |
+ result = runner.invoke( |
|
5411 | 5338 |
cli.derivepassphrase, |
5412 | 5339 |
[option, '0', '-p', '--', DUMMY_SERVICE], |
5413 | 5340 |
input=DUMMY_PASSPHRASE, |
5414 | 5341 |
catch_exceptions=False, |
5415 | 5342 |
) |
5416 |
- result = tests.ReadableResult.parse(result_) |
|
5417 | 5343 |
assert result.clean_exit(empty_stderr=False), 'expected clean exit' |
5418 | 5344 |
assert tests.deprecation_warning_emitted( |
5419 | 5345 |
'A subcommand will be required here in v1.0', caplog.record_tuples |
... | ... |
@@ -5422,7 +5348,7 @@ class TestCLITransition: |
5422 | 5348 |
'Defaulting to subcommand "vault"', caplog.record_tuples |
5423 | 5349 |
) |
5424 | 5350 |
for c in charset: |
5425 |
- assert c not in result.output, ( |
|
5351 |
+ assert c not in result.stdout, ( |
|
5426 | 5352 |
f'derived password contains forbidden character {c!r}' |
5427 | 5353 |
) |
5428 | 5354 |
|
... | ... |
@@ -5431,7 +5357,7 @@ class TestCLITransition: |
5431 | 5357 |
caplog: pytest.LogCaptureFixture, |
5432 | 5358 |
) -> None: |
5433 | 5359 |
"""Deferring from top-level to "vault" works.""" |
5434 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5360 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5435 | 5361 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5436 | 5362 |
# with-statements. |
5437 | 5363 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5443,13 +5369,12 @@ class TestCLITransition: |
5443 | 5369 |
runner=runner, |
5444 | 5370 |
) |
5445 | 5371 |
) |
5446 |
- result_ = runner.invoke( |
|
5372 |
+ result = runner.invoke( |
|
5447 | 5373 |
cli.derivepassphrase, |
5448 | 5374 |
[], |
5449 | 5375 |
input=DUMMY_PASSPHRASE, |
5450 | 5376 |
catch_exceptions=False, |
5451 | 5377 |
) |
5452 |
- result = tests.ReadableResult.parse(result_) |
|
5453 | 5378 |
assert tests.deprecation_warning_emitted( |
5454 | 5379 |
'A subcommand will be required here in v1.0', caplog.record_tuples |
5455 | 5380 |
) |
... | ... |
@@ -5466,7 +5391,7 @@ class TestCLITransition: |
5466 | 5391 |
) -> None: |
5467 | 5392 |
"""Exporting from (and migrating) the old settings file works.""" |
5468 | 5393 |
caplog.set_level(logging.INFO) |
5469 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5394 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5470 | 5395 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5471 | 5396 |
# with-statements. |
5472 | 5397 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5488,12 +5413,11 @@ class TestCLITransition: |
5488 | 5413 |
+ '\n', |
5489 | 5414 |
encoding='UTF-8', |
5490 | 5415 |
) |
5491 |
- result_ = runner.invoke( |
|
5416 |
+ result = runner.invoke( |
|
5492 | 5417 |
cli.derivepassphrase_vault, |
5493 | 5418 |
['--export', '-'], |
5494 | 5419 |
catch_exceptions=False, |
5495 | 5420 |
) |
5496 |
- result = tests.ReadableResult.parse(result_) |
|
5497 | 5421 |
assert result.clean_exit(), 'expected clean exit' |
5498 | 5422 |
assert tests.deprecation_warning_emitted( |
5499 | 5423 |
'v0.1-style config file', caplog.record_tuples |
... | ... |
@@ -5507,7 +5431,7 @@ class TestCLITransition: |
5507 | 5431 |
caplog: pytest.LogCaptureFixture, |
5508 | 5432 |
) -> None: |
5509 | 5433 |
"""Exporting from (and not migrating) the old settings file fails.""" |
5510 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5434 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5511 | 5435 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5512 | 5436 |
# with-statements. |
5513 | 5437 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5539,12 +5463,11 @@ class TestCLITransition: |
5539 | 5463 |
|
5540 | 5464 |
monkeypatch.setattr(os, 'replace', raiser) |
5541 | 5465 |
monkeypatch.setattr(pathlib.Path, 'rename', raiser) |
5542 |
- result_ = runner.invoke( |
|
5466 |
+ result = runner.invoke( |
|
5543 | 5467 |
cli.derivepassphrase_vault, |
5544 | 5468 |
['--export', '-'], |
5545 | 5469 |
catch_exceptions=False, |
5546 | 5470 |
) |
5547 |
- result = tests.ReadableResult.parse(result_) |
|
5548 | 5471 |
assert result.clean_exit(), 'expected clean exit' |
5549 | 5472 |
assert tests.deprecation_warning_emitted( |
5550 | 5473 |
'v0.1-style config file', caplog.record_tuples |
... | ... |
@@ -5558,7 +5481,7 @@ class TestCLITransition: |
5558 | 5481 |
) -> None: |
5559 | 5482 |
"""Completing service names from the old settings file works.""" |
5560 | 5483 |
config = {'services': {DUMMY_SERVICE: DUMMY_CONFIG_SETTINGS.copy()}} |
5561 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
5484 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
5562 | 5485 |
# TODO(the-13th-letter): Rewrite using parenthesized |
5563 | 5486 |
# with-statements. |
5564 | 5487 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -5714,7 +5637,7 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5714 | 5637 |
def __init__(self) -> None: |
5715 | 5638 |
"""Initialize self, set up context managers and enter them.""" |
5716 | 5639 |
super().__init__() |
5717 |
- self.runner = click.testing.CliRunner(mix_stderr=False) |
|
5640 |
+ self.runner = tests.CliRunner(mix_stderr=False) |
|
5718 | 5641 |
self.exit_stack = contextlib.ExitStack().__enter__() |
5719 | 5642 |
self.monkeypatch = self.exit_stack.enter_context( |
5720 | 5643 |
pytest.MonkeyPatch().context() |
... | ... |
@@ -5834,7 +5757,7 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5834 | 5757 |
# NOTE: This relies on settings_obj containing only the keys |
5835 | 5758 |
# "length", "repeat", "upper", "lower", "number", "space", |
5836 | 5759 |
# "dash" and "symbol". |
5837 |
- result_ = self.runner.invoke( |
|
5760 |
+ result = self.runner.invoke( |
|
5838 | 5761 |
cli.derivepassphrase_vault, |
5839 | 5762 |
[ |
5840 | 5763 |
'--config', |
... | ... |
@@ -5848,7 +5771,6 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5848 | 5771 |
], |
5849 | 5772 |
catch_exceptions=False, |
5850 | 5773 |
) |
5851 |
- result = tests.ReadableResult.parse(result_) |
|
5852 | 5774 |
assert result.clean_exit(empty_stderr=False) |
5853 | 5775 |
assert cli_helpers.load_config() == config |
5854 | 5776 |
return config |
... | ... |
@@ -5907,7 +5829,7 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5907 | 5829 |
# NOTE: This relies on settings_obj containing only the keys |
5908 | 5830 |
# "length", "repeat", "upper", "lower", "number", "space", |
5909 | 5831 |
# "dash" and "symbol". |
5910 |
- result_ = self.runner.invoke( |
|
5832 |
+ result = self.runner.invoke( |
|
5911 | 5833 |
cli.derivepassphrase_vault, |
5912 | 5834 |
[ |
5913 | 5835 |
'--config', |
... | ... |
@@ -5922,7 +5844,6 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5922 | 5844 |
+ ['--', service], |
5923 | 5845 |
catch_exceptions=False, |
5924 | 5846 |
) |
5925 |
- result = tests.ReadableResult.parse(result_) |
|
5926 | 5847 |
assert result.clean_exit(empty_stderr=False) |
5927 | 5848 |
assert cli_helpers.load_config() == config |
5928 | 5849 |
return config |
... | ... |
@@ -5947,13 +5868,12 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5947 | 5868 |
""" |
5948 | 5869 |
cli_helpers.save_config(config) |
5949 | 5870 |
config.pop('global', None) |
5950 |
- result_ = self.runner.invoke( |
|
5871 |
+ result = self.runner.invoke( |
|
5951 | 5872 |
cli.derivepassphrase_vault, |
5952 | 5873 |
['--delete-globals'], |
5953 | 5874 |
input='y', |
5954 | 5875 |
catch_exceptions=False, |
5955 | 5876 |
) |
5956 |
- result = tests.ReadableResult.parse(result_) |
|
5957 | 5877 |
assert result.clean_exit(empty_stderr=False) |
5958 | 5878 |
assert cli_helpers.load_config() == config |
5959 | 5879 |
return config |
... | ... |
@@ -5987,13 +5907,12 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
5987 | 5907 |
config, service = config_and_service |
5988 | 5908 |
cli_helpers.save_config(config) |
5989 | 5909 |
config['services'].pop(service, None) |
5990 |
- result_ = self.runner.invoke( |
|
5910 |
+ result = self.runner.invoke( |
|
5991 | 5911 |
cli.derivepassphrase_vault, |
5992 | 5912 |
['--delete', '--', service], |
5993 | 5913 |
input='y', |
5994 | 5914 |
catch_exceptions=False, |
5995 | 5915 |
) |
5996 |
- result = tests.ReadableResult.parse(result_) |
|
5997 | 5916 |
assert result.clean_exit(empty_stderr=False) |
5998 | 5917 |
assert cli_helpers.load_config() == config |
5999 | 5918 |
return config |
... | ... |
@@ -6018,13 +5937,12 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
6018 | 5937 |
""" |
6019 | 5938 |
cli_helpers.save_config(config) |
6020 | 5939 |
config = {'services': {}} |
6021 |
- result_ = self.runner.invoke( |
|
5940 |
+ result = self.runner.invoke( |
|
6022 | 5941 |
cli.derivepassphrase_vault, |
6023 | 5942 |
['--clear'], |
6024 | 5943 |
input='y', |
6025 | 5944 |
catch_exceptions=False, |
6026 | 5945 |
) |
6027 |
- result = tests.ReadableResult.parse(result_) |
|
6028 | 5946 |
assert result.clean_exit(empty_stderr=False) |
6029 | 5947 |
assert cli_helpers.load_config() == config |
6030 | 5948 |
return config |
... | ... |
@@ -6064,16 +5982,14 @@ class ConfigManagementStateMachine(stateful.RuleBasedStateMachine): |
6064 | 5982 |
else config_to_import |
6065 | 5983 |
) |
6066 | 5984 |
assert _types.is_vault_config(config) |
6067 |
- result_ = self.runner.invoke( |
|
5985 |
+ result = self.runner.invoke( |
|
6068 | 5986 |
cli.derivepassphrase_vault, |
6069 | 5987 |
['--import', '-'] |
6070 | 5988 |
+ (['--overwrite-existing'] if overwrite else []), |
6071 | 5989 |
input=json.dumps(config_to_import), |
6072 | 5990 |
catch_exceptions=False, |
6073 | 5991 |
) |
6074 |
- assert tests.ReadableResult.parse(result_).clean_exit( |
|
6075 |
- empty_stderr=False |
|
6076 |
- ) |
|
5992 |
+ assert result.clean_exit(empty_stderr=False) |
|
6077 | 5993 |
assert cli_helpers.load_config() == config |
6078 | 5994 |
return config |
6079 | 5995 |
|
... | ... |
@@ -6202,7 +6118,7 @@ class TestShellCompletion: |
6202 | 6118 |
completions: AbstractSet[str], |
6203 | 6119 |
) -> None: |
6204 | 6120 |
"""Our completion machinery works for vault service names.""" |
6205 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
6121 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
6206 | 6122 |
# TODO(the-13th-letter): Rewrite using parenthesized |
6207 | 6123 |
# with-statements. |
6208 | 6124 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -6234,7 +6150,7 @@ class TestShellCompletion: |
6234 | 6150 |
results: list[str | click.shell_completion.CompletionItem], |
6235 | 6151 |
) -> None: |
6236 | 6152 |
"""Custom completion functions work for all shells.""" |
6237 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
6153 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
6238 | 6154 |
# TODO(the-13th-letter): Rewrite using parenthesized |
6239 | 6155 |
# with-statements. |
6240 | 6156 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -6296,7 +6212,7 @@ class TestShellCompletion: |
6296 | 6212 |
) -> None: |
6297 | 6213 |
"""Completion skips incompletable items.""" |
6298 | 6214 |
vault_config = config if mode == 'config' else {'services': {}} |
6299 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
6215 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
6300 | 6216 |
# TODO(the-13th-letter): Rewrite using parenthesized |
6301 | 6217 |
# with-statements. |
6302 | 6218 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -6310,19 +6226,18 @@ class TestShellCompletion: |
6310 | 6226 |
) |
6311 | 6227 |
) |
6312 | 6228 |
if mode == 'config': |
6313 |
- result_ = runner.invoke( |
|
6229 |
+ result = runner.invoke( |
|
6314 | 6230 |
cli.derivepassphrase_vault, |
6315 | 6231 |
['--config', '--length=10', '--', key], |
6316 | 6232 |
catch_exceptions=False, |
6317 | 6233 |
) |
6318 | 6234 |
else: |
6319 |
- result_ = runner.invoke( |
|
6235 |
+ result = runner.invoke( |
|
6320 | 6236 |
cli.derivepassphrase_vault, |
6321 | 6237 |
['--import', '-'], |
6322 | 6238 |
catch_exceptions=False, |
6323 | 6239 |
input=json.dumps(config), |
6324 | 6240 |
) |
6325 |
- result = tests.ReadableResult.parse(result_) |
|
6326 | 6241 |
assert result.clean_exit(), 'expected clean exit' |
6327 | 6242 |
assert tests.warning_emitted( |
6328 | 6243 |
'contains an ASCII control character', caplog.record_tuples |
... | ... |
@@ -6338,7 +6253,7 @@ class TestShellCompletion: |
6338 | 6253 |
self, |
6339 | 6254 |
) -> None: |
6340 | 6255 |
"""Service name completion quietly fails on missing configuration.""" |
6341 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
6256 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
6342 | 6257 |
# TODO(the-13th-letter): Rewrite using parenthesized |
6343 | 6258 |
# with-statements. |
6344 | 6259 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -6368,7 +6283,7 @@ class TestShellCompletion: |
6368 | 6283 |
exc_type: type[Exception], |
6369 | 6284 |
) -> None: |
6370 | 6285 |
"""Service name completion quietly fails on configuration errors.""" |
6371 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
6286 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
6372 | 6287 |
# TODO(the-13th-letter): Rewrite using parenthesized |
6373 | 6288 |
# with-statements. |
6374 | 6289 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -11,7 +11,6 @@ import pathlib |
11 | 11 |
import types |
12 | 12 |
from typing import TYPE_CHECKING |
13 | 13 |
|
14 |
-import click.testing |
|
15 | 14 |
import hypothesis |
16 | 15 |
import pytest |
17 | 16 |
from hypothesis import strategies |
... | ... |
@@ -186,7 +185,7 @@ class TestCLI: |
186 | 185 |
[`exporter.get_vault_path`][] for details. |
187 | 186 |
|
188 | 187 |
""" |
189 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
188 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
190 | 189 |
# TODO(the-13th-letter): Rewrite using parenthesized |
191 | 190 |
# with-statements. |
192 | 191 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -201,17 +200,16 @@ class TestCLI: |
201 | 200 |
) |
202 | 201 |
) |
203 | 202 |
monkeypatch.setenv('VAULT_KEY', tests.VAULT_MASTER_KEY) |
204 |
- result_ = runner.invoke( |
|
203 |
+ result = runner.invoke( |
|
205 | 204 |
cli.derivepassphrase_export_vault, |
206 | 205 |
['VAULT_PATH'], |
207 | 206 |
) |
208 |
- result = tests.ReadableResult.parse(result_) |
|
209 | 207 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
210 |
- assert json.loads(result.output) == tests.VAULT_V03_CONFIG_DATA |
|
208 |
+ assert json.loads(result.stdout) == tests.VAULT_V03_CONFIG_DATA |
|
211 | 209 |
|
212 | 210 |
def test_201_key_parameter(self) -> None: |
213 | 211 |
"""The `--key` option is supported.""" |
214 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
212 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
215 | 213 |
# TODO(the-13th-letter): Rewrite using parenthesized |
216 | 214 |
# with-statements. |
217 | 215 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -224,13 +222,12 @@ class TestCLI: |
224 | 222 |
vault_config=tests.VAULT_V03_CONFIG, |
225 | 223 |
) |
226 | 224 |
) |
227 |
- result_ = runner.invoke( |
|
225 |
+ result = runner.invoke( |
|
228 | 226 |
cli.derivepassphrase_export_vault, |
229 | 227 |
['-k', tests.VAULT_MASTER_KEY, '.vault'], |
230 | 228 |
) |
231 |
- result = tests.ReadableResult.parse(result_) |
|
232 | 229 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
233 |
- assert json.loads(result.output) == tests.VAULT_V03_CONFIG_DATA |
|
230 |
+ assert json.loads(result.stdout) == tests.VAULT_V03_CONFIG_DATA |
|
234 | 231 |
|
235 | 232 |
@tests.Parametrize.VAULT_CONFIG_FORMATS_DATA |
236 | 233 |
def test_210_load_vault_v02_v03_storeroom( |
... | ... |
@@ -245,7 +242,7 @@ class TestCLI: |
245 | 242 |
vault` to only attempt decoding in that named format. |
246 | 243 |
|
247 | 244 |
""" |
248 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
245 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
249 | 246 |
# TODO(the-13th-letter): Rewrite using parenthesized |
250 | 247 |
# with-statements. |
251 | 248 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -258,13 +255,12 @@ class TestCLI: |
258 | 255 |
vault_config=config, |
259 | 256 |
) |
260 | 257 |
) |
261 |
- result_ = runner.invoke( |
|
258 |
+ result = runner.invoke( |
|
262 | 259 |
cli.derivepassphrase_export_vault, |
263 | 260 |
['-f', format, '-k', tests.VAULT_MASTER_KEY, 'VAULT_PATH'], |
264 | 261 |
) |
265 |
- result = tests.ReadableResult.parse(result_) |
|
266 | 262 |
assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
267 |
- assert json.loads(result.output) == config_data |
|
263 |
+ assert json.loads(result.stdout) == config_data |
|
268 | 264 |
|
269 | 265 |
# test_300_invalid_format is found in |
270 | 266 |
# tests.test_derivepassphrase_export::Test002CLI |
... | ... |
@@ -274,7 +270,7 @@ class TestCLI: |
274 | 270 |
caplog: pytest.LogCaptureFixture, |
275 | 271 |
) -> None: |
276 | 272 |
"""Fail when trying to decode non-existant files/directories.""" |
277 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
273 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
278 | 274 |
# TODO(the-13th-letter): Rewrite using parenthesized |
279 | 275 |
# with-statements. |
280 | 276 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -288,11 +284,10 @@ class TestCLI: |
288 | 284 |
vault_key=tests.VAULT_MASTER_KEY, |
289 | 285 |
) |
290 | 286 |
) |
291 |
- result_ = runner.invoke( |
|
287 |
+ result = runner.invoke( |
|
292 | 288 |
cli.derivepassphrase_export_vault, |
293 | 289 |
['does-not-exist.txt'], |
294 | 290 |
) |
295 |
- result = tests.ReadableResult.parse(result_) |
|
296 | 291 |
assert result.error_exit( |
297 | 292 |
error=( |
298 | 293 |
"Cannot parse 'does-not-exist.txt' " |
... | ... |
@@ -307,7 +302,7 @@ class TestCLI: |
307 | 302 |
caplog: pytest.LogCaptureFixture, |
308 | 303 |
) -> None: |
309 | 304 |
"""Fail to parse invalid vault configurations (files).""" |
310 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
305 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
311 | 306 |
# TODO(the-13th-letter): Rewrite using parenthesized |
312 | 307 |
# with-statements. |
313 | 308 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -321,11 +316,10 @@ class TestCLI: |
321 | 316 |
vault_key=tests.VAULT_MASTER_KEY, |
322 | 317 |
) |
323 | 318 |
) |
324 |
- result_ = runner.invoke( |
|
319 |
+ result = runner.invoke( |
|
325 | 320 |
cli.derivepassphrase_export_vault, |
326 | 321 |
['.vault'], |
327 | 322 |
) |
328 |
- result = tests.ReadableResult.parse(result_) |
|
329 | 323 |
assert result.error_exit( |
330 | 324 |
error="Cannot parse '.vault' as a valid vault-native config", |
331 | 325 |
record_tuples=caplog.record_tuples, |
... | ... |
@@ -337,7 +331,7 @@ class TestCLI: |
337 | 331 |
caplog: pytest.LogCaptureFixture, |
338 | 332 |
) -> None: |
339 | 333 |
"""Fail to parse invalid vault configurations (directories).""" |
340 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
334 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
341 | 335 |
# TODO(the-13th-letter): Rewrite using parenthesized |
342 | 336 |
# with-statements. |
343 | 337 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -354,11 +348,10 @@ class TestCLI: |
354 | 348 |
p = pathlib.Path('.vault') |
355 | 349 |
p.unlink() |
356 | 350 |
p.mkdir() |
357 |
- result_ = runner.invoke( |
|
351 |
+ result = runner.invoke( |
|
358 | 352 |
cli.derivepassphrase_export_vault, |
359 | 353 |
[str(p)], |
360 | 354 |
) |
361 |
- result = tests.ReadableResult.parse(result_) |
|
362 | 355 |
assert result.error_exit( |
363 | 356 |
error="Cannot parse '.vault' as a valid vault-native config", |
364 | 357 |
record_tuples=caplog.record_tuples, |
... | ... |
@@ -370,7 +363,7 @@ class TestCLI: |
370 | 363 |
caplog: pytest.LogCaptureFixture, |
371 | 364 |
) -> None: |
372 | 365 |
"""Fail to parse vault configurations with invalid integrity checks.""" |
373 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
366 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
374 | 367 |
# TODO(the-13th-letter): Rewrite using parenthesized |
375 | 368 |
# with-statements. |
376 | 369 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -384,11 +377,10 @@ class TestCLI: |
384 | 377 |
vault_key=tests.VAULT_MASTER_KEY, |
385 | 378 |
) |
386 | 379 |
) |
387 |
- result_ = runner.invoke( |
|
380 |
+ result = runner.invoke( |
|
388 | 381 |
cli.derivepassphrase_export_vault, |
389 | 382 |
['-f', 'v0.3', '.vault'], |
390 | 383 |
) |
391 |
- result = tests.ReadableResult.parse(result_) |
|
392 | 384 |
assert result.error_exit( |
393 | 385 |
error="Cannot parse '.vault' as a valid vault-native config", |
394 | 386 |
record_tuples=caplog.record_tuples, |
... | ... |
@@ -400,7 +392,7 @@ class TestCLI: |
400 | 392 |
caplog: pytest.LogCaptureFixture, |
401 | 393 |
) -> None: |
402 | 394 |
"""The decoded vault configuration data is valid.""" |
403 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
395 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
404 | 396 |
# TODO(the-13th-letter): Rewrite using parenthesized |
405 | 397 |
# with-statements. |
406 | 398 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -423,11 +415,10 @@ class TestCLI: |
423 | 415 |
'export_vault_config_data', |
424 | 416 |
export_vault_config_data, |
425 | 417 |
) |
426 |
- result_ = runner.invoke( |
|
418 |
+ result = runner.invoke( |
|
427 | 419 |
cli.derivepassphrase_export_vault, |
428 | 420 |
['.vault'], |
429 | 421 |
) |
430 |
- result = tests.ReadableResult.parse(result_) |
|
431 | 422 |
assert result.error_exit( |
432 | 423 |
error='Invalid vault config: ', |
433 | 424 |
record_tuples=caplog.record_tuples, |
... | ... |
@@ -453,7 +444,7 @@ class TestStoreroom: |
453 | 444 |
them as well. |
454 | 445 |
|
455 | 446 |
""" |
456 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
447 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
457 | 448 |
# TODO(the-13th-letter): Rewrite using parenthesized |
458 | 449 |
# with-statements. |
459 | 450 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -496,7 +487,7 @@ class TestStoreroom: |
496 | 487 |
wrong shape. |
497 | 488 |
|
498 | 489 |
""" |
499 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
490 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
500 | 491 |
master_keys = _types.StoreroomMasterKeys( |
501 | 492 |
encryption_key=bytes(storeroom.KEY_SIZE), |
502 | 493 |
signing_key=bytes(storeroom.KEY_SIZE), |
... | ... |
@@ -533,7 +524,7 @@ class TestStoreroom: |
533 | 524 |
These include unknown versions, and data of the wrong shape. |
534 | 525 |
|
535 | 526 |
""" |
536 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
527 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
537 | 528 |
# TODO(the-13th-letter): Rewrite using parenthesized |
538 | 529 |
# with-statements. |
539 | 530 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -575,7 +566,7 @@ class TestStoreroom: |
575 | 566 |
subdirectories. |
576 | 567 |
|
577 | 568 |
""" |
578 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
569 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
579 | 570 |
# TODO(the-13th-letter): Rewrite using parenthesized |
580 | 571 |
# with-statements. |
581 | 572 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -701,7 +692,7 @@ class TestVaultNativeConfig: |
701 | 692 |
no longer does. |
702 | 693 |
|
703 | 694 |
""" |
704 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
695 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
705 | 696 |
# TODO(the-13th-letter): Rewrite using parenthesized |
706 | 697 |
# with-statements. |
707 | 698 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -737,7 +728,7 @@ class TestVaultNativeConfig: |
737 | 728 |
them as well. |
738 | 729 |
|
739 | 730 |
""" |
740 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
731 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
741 | 732 |
# TODO(the-13th-letter): Rewrite using parenthesized |
742 | 733 |
# with-statements. |
743 | 734 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -772,7 +763,7 @@ class TestVaultNativeConfig: |
772 | 763 |
|
773 | 764 |
return func |
774 | 765 |
|
775 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
766 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
776 | 767 |
# TODO(the-13th-letter): Rewrite using parenthesized |
777 | 768 |
# with-statements. |
778 | 769 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -12,7 +12,6 @@ import string |
12 | 12 |
import types |
13 | 13 |
from typing import TYPE_CHECKING, Any, NamedTuple |
14 | 14 |
|
15 |
-import click.testing |
|
16 | 15 |
import hypothesis |
17 | 16 |
import pytest |
18 | 17 |
from hypothesis import strategies |
... | ... |
@@ -206,7 +205,7 @@ class Test001ExporterUtils: |
206 | 205 |
('USER', user), |
207 | 206 |
('USERNAME', username), |
208 | 207 |
] |
209 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
208 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
210 | 209 |
# TODO(the-13th-letter): Rewrite using parenthesized |
211 | 210 |
# with-statements. |
212 | 211 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -233,7 +232,7 @@ class Test001ExporterUtils: |
233 | 232 |
Handle relative paths, absolute paths, and missing paths. |
234 | 233 |
|
235 | 234 |
""" |
236 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
235 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
237 | 236 |
# TODO(the-13th-letter): Rewrite using parenthesized |
238 | 237 |
# with-statements. |
239 | 238 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -378,7 +377,7 @@ class Test002CLI: |
378 | 377 |
|
379 | 378 |
def test_300_invalid_format(self) -> None: |
380 | 379 |
"""Reject invalid vault configuration format names.""" |
381 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
380 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
382 | 381 |
# TODO(the-13th-letter): Rewrite using parenthesized |
383 | 382 |
# with-statements. |
384 | 383 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -392,12 +391,11 @@ class Test002CLI: |
392 | 391 |
vault_key=tests.VAULT_MASTER_KEY, |
393 | 392 |
) |
394 | 393 |
) |
395 |
- result_ = runner.invoke( |
|
394 |
+ result = runner.invoke( |
|
396 | 395 |
cli.derivepassphrase_export_vault, |
397 | 396 |
['-f', 'INVALID', 'VAULT_PATH'], |
398 | 397 |
catch_exceptions=False, |
399 | 398 |
) |
400 |
- result = tests.ReadableResult.parse(result_) |
|
401 | 399 |
for snippet in ('Invalid value for', '-f', '--format', 'INVALID'): |
402 | 400 |
assert result.error_exit(error=snippet), ( |
403 | 401 |
'expected error exit and known error message' |
... | ... |
@@ -414,7 +412,7 @@ class Test002CLI: |
414 | 412 |
) -> None: |
415 | 413 |
"""Abort export call if no cryptography is available.""" |
416 | 414 |
del config_data |
417 |
- runner = click.testing.CliRunner(mix_stderr=False) |
|
415 |
+ runner = tests.CliRunner(mix_stderr=False) |
|
418 | 416 |
# TODO(the-13th-letter): Rewrite using parenthesized |
419 | 417 |
# with-statements. |
420 | 418 |
# https://the13thletter.info/derivepassphrase/latest/pycompatibility/#after-eol-py3.9 |
... | ... |
@@ -428,12 +426,11 @@ class Test002CLI: |
428 | 426 |
vault_key=tests.VAULT_MASTER_KEY, |
429 | 427 |
) |
430 | 428 |
) |
431 |
- result_ = runner.invoke( |
|
429 |
+ result = runner.invoke( |
|
432 | 430 |
cli.derivepassphrase_export_vault, |
433 | 431 |
['-f', format, 'VAULT_PATH'], |
434 | 432 |
catch_exceptions=False, |
435 | 433 |
) |
436 |
- result = tests.ReadableResult.parse(result_) |
|
437 | 434 |
assert result.error_exit( |
438 | 435 |
error=tests.CANNOT_LOAD_CRYPTOGRAPHY, |
439 | 436 |
record_tuples=caplog.record_tuples, |
... | ... |
@@ -694,14 +694,13 @@ class TestAgentInteraction: |
694 | 694 |
|
695 | 695 |
# TODO(the-13th-letter): (Continued from above.) Update input |
696 | 696 |
# data to use `index`/`input` directly and unconditionally. |
697 |
- runner = click.testing.CliRunner(mix_stderr=True) |
|
698 |
- result_ = runner.invoke( |
|
697 |
+ runner = tests.CliRunner(mix_stderr=True) |
|
698 |
+ result = runner.invoke( |
|
699 | 699 |
driver, |
700 | 700 |
[], |
701 | 701 |
input=('yes\n' if single else f'{index}\n'), |
702 | 702 |
catch_exceptions=True, |
703 | 703 |
) |
704 |
- result = tests.ReadableResult.parse(result_) |
|
705 | 704 |
for snippet in ('Suitable SSH keys:\n', text, f'\n{b64_key}\n'): |
706 | 705 |
assert result.clean_exit(output=snippet), 'expected clean exit' |
707 | 706 |
|
708 | 707 |