Marco Ricci commited on 2025-01-01 14:08:48
Zeige 2 geänderte Dateien mit 120 Einfügungen und 7 Löschungen.
These sections no longer need be excluded from coverage.
| ... | ... |
@@ -993,7 +993,7 @@ def version_option_callback( |
| 993 | 993 |
ctx: click.Context, |
| 994 | 994 |
param: click.Parameter, |
| 995 | 995 |
value: bool, # noqa: FBT001 |
| 996 |
-) -> None: # pragma: no cover |
|
| 996 |
+) -> None: |
|
| 997 | 997 |
del param |
| 998 | 998 |
if value and not ctx.resilient_parsing: |
| 999 | 999 |
click.echo( |
| ... | ... |
@@ -1027,9 +1027,9 @@ def color_forcing_callback( |
| 1027 | 1027 |
) -> None: |
| 1028 | 1028 |
"""Force the `click` context to honor `NO_COLOR` and `FORCE_COLOR`.""" |
| 1029 | 1029 |
del param, value |
| 1030 |
- if os.environ.get('NO_COLOR'): # pragma: no cover
|
|
| 1030 |
+ if os.environ.get('NO_COLOR'):
|
|
| 1031 | 1031 |
ctx.color = False |
| 1032 |
- if os.environ.get('FORCE_COLOR'): # pragma: no cover
|
|
| 1032 |
+ if os.environ.get('FORCE_COLOR'):
|
|
| 1033 | 1033 |
ctx.color = True |
| 1034 | 1034 |
|
| 1035 | 1035 |
|
| ... | ... |
@@ -2730,13 +2730,13 @@ def derivepassphrase_vault( # noqa: C901,PLR0912,PLR0913,PLR0914,PLR0915 |
| 2730 | 2730 |
group = LoggingOption |
| 2731 | 2731 |
elif isinstance(param, CompatibilityOption): |
| 2732 | 2732 |
group = CompatibilityOption |
| 2733 |
- elif isinstance(param, StandardOption): # pragma: no branch |
|
| 2733 |
+ elif isinstance(param, StandardOption): |
|
| 2734 | 2734 |
group = StandardOption |
| 2735 | 2735 |
elif isinstance(param, OptionGroupOption): # pragma: no cover |
| 2736 | 2736 |
raise AssertionError( # noqa: DOC501,TRY003,TRY004 |
| 2737 | 2737 |
f'Unknown option group for {param!r}' # noqa: EM102
|
| 2738 | 2738 |
) |
| 2739 |
- else: # pragma: no cover |
|
| 2739 |
+ else: |
|
| 2740 | 2740 |
group = click.Option |
| 2741 | 2741 |
options_in_group.setdefault(group, []).append(param) |
| 2742 | 2742 |
params_by_str[param.human_readable_name] = param |
| ... | ... |
@@ -280,15 +280,106 @@ def vault_config_exporter_shell_interpreter( # noqa: C901 |
| 280 | 280 |
) |
| 281 | 281 |
|
| 282 | 282 |
|
| 283 |
+class TestAllCLI: |
|
| 284 |
+ @pytest.mark.parametrize( |
|
| 285 |
+ ['command', 'non_eager_arguments'], |
|
| 286 |
+ [ |
|
| 287 |
+ ([], []), |
|
| 288 |
+ ([], ['export']), |
|
| 289 |
+ (['export'], []), |
|
| 290 |
+ (['export'], ['vault']), |
|
| 291 |
+ (['export', 'vault'], []), |
|
| 292 |
+ (['export', 'vault'], ['--format', 'this-format-doesnt-exist']), |
|
| 293 |
+ (['vault'], []), |
|
| 294 |
+ (['vault'], ['--export', './']), |
|
| 295 |
+ ] |
|
| 296 |
+ ) |
|
| 297 |
+ @pytest.mark.parametrize('arguments', [['--help'], ['--version']])
|
|
| 298 |
+ def test_200_eager_options( |
|
| 299 |
+ self, |
|
| 300 |
+ monkeypatch: pytest.MonkeyPatch, |
|
| 301 |
+ command: list[str], |
|
| 302 |
+ arguments: list[str], |
|
| 303 |
+ non_eager_arguments: list[str], |
|
| 304 |
+ ) -> None: |
|
| 305 |
+ runner = click.testing.CliRunner(mix_stderr=False) |
|
| 306 |
+ with tests.isolated_config( |
|
| 307 |
+ monkeypatch=monkeypatch, |
|
| 308 |
+ runner=runner, |
|
| 309 |
+ ): |
|
| 310 |
+ _result = runner.invoke( |
|
| 311 |
+ cli.derivepassphrase, |
|
| 312 |
+ [*command, *arguments, *non_eager_arguments], |
|
| 313 |
+ catch_exceptions=False, |
|
| 314 |
+ ) |
|
| 315 |
+ result = tests.ReadableResult.parse(_result) |
|
| 316 |
+ assert result.clean_exit(empty_stderr=True), 'expected clean exit' |
|
| 317 |
+ |
|
| 318 |
+ @pytest.mark.parametrize('no_color', [False, True])
|
|
| 319 |
+ @pytest.mark.parametrize('force_color', [False, True])
|
|
| 320 |
+ @pytest.mark.parametrize('isatty', [False, True])
|
|
| 321 |
+ @pytest.mark.parametrize( |
|
| 322 |
+ ['command_line', 'input'], |
|
| 323 |
+ [ |
|
| 324 |
+ ( |
|
| 325 |
+ ['vault', '--import', '-'], |
|
| 326 |
+ '{"services": {"": {"length": 20}}}',
|
|
| 327 |
+ ), |
|
| 328 |
+ ] |
|
| 329 |
+ ) |
|
| 330 |
+ def test_201_no_color_force_color( |
|
| 331 |
+ self, |
|
| 332 |
+ monkeypatch: pytest.MonkeyPatch, |
|
| 333 |
+ no_color: bool, |
|
| 334 |
+ force_color: bool, |
|
| 335 |
+ isatty: bool, |
|
| 336 |
+ command_line: list[str], |
|
| 337 |
+ input: str | None, |
|
| 338 |
+ ) -> None: |
|
| 339 |
+ # Force color on if force_color. Otherwise force color off if |
|
| 340 |
+ # no_color. Otherwise set color if and only if we have a TTY. |
|
| 341 |
+ color = force_color or not no_color if isatty else force_color |
|
| 342 |
+ runner = click.testing.CliRunner(mix_stderr=False) |
|
| 343 |
+ with tests.isolated_config( |
|
| 344 |
+ monkeypatch=monkeypatch, |
|
| 345 |
+ runner=runner, |
|
| 346 |
+ ): |
|
| 347 |
+ if no_color: |
|
| 348 |
+ monkeypatch.setenv('NO_COLOR', 'yes')
|
|
| 349 |
+ if force_color: |
|
| 350 |
+ monkeypatch.setenv('FORCE_COLOR', 'yes')
|
|
| 351 |
+ _result = runner.invoke( |
|
| 352 |
+ cli.derivepassphrase, |
|
| 353 |
+ command_line, |
|
| 354 |
+ input=input, |
|
| 355 |
+ catch_exceptions=False, |
|
| 356 |
+ color=isatty, |
|
| 357 |
+ ) |
|
| 358 |
+ result = tests.ReadableResult.parse(_result) |
|
| 359 |
+ assert ( |
|
| 360 |
+ not color |
|
| 361 |
+ or '\x1b[0m' in result.stderr |
|
| 362 |
+ or '\x1b[m' in result.stderr |
|
| 363 |
+ ), 'Expected color, but found no ANSI reset sequence' |
|
| 364 |
+ assert ( |
|
| 365 |
+ color or '\x1b[' not in result.stderr |
|
| 366 |
+ ), 'Expected no color, but found an ANSI control sequence' |
|
| 367 |
+ |
|
| 368 |
+ |
|
| 283 | 369 |
class TestCLI: |
| 284 |
- def test_200_help_output(self, monkeypatch: pytest.MonkeyPatch) -> None: |
|
| 370 |
+ def test_200_help_output( |
|
| 371 |
+ self, |
|
| 372 |
+ monkeypatch: pytest.MonkeyPatch, |
|
| 373 |
+ ) -> None: |
|
| 285 | 374 |
runner = click.testing.CliRunner(mix_stderr=False) |
| 286 | 375 |
with tests.isolated_config( |
| 287 | 376 |
monkeypatch=monkeypatch, |
| 288 | 377 |
runner=runner, |
| 289 | 378 |
): |
| 290 | 379 |
_result = runner.invoke( |
| 291 |
- cli.derivepassphrase_vault, ['--help'], catch_exceptions=False |
|
| 380 |
+ cli.derivepassphrase_vault, |
|
| 381 |
+ ['--help'], |
|
| 382 |
+ catch_exceptions=False, |
|
| 292 | 383 |
) |
| 293 | 384 |
result = tests.ReadableResult.parse(_result) |
| 294 | 385 |
assert result.clean_exit( |
| ... | ... |
@@ -298,6 +389,28 @@ class TestCLI: |
| 298 | 389 |
empty_stderr=True, output='Use $VISUAL or $EDITOR to configure' |
| 299 | 390 |
), 'expected clean exit, and option group epilog in help text' |
| 300 | 391 |
|
| 392 |
+ def test_200a_version_output( |
|
| 393 |
+ self, |
|
| 394 |
+ monkeypatch: pytest.MonkeyPatch, |
|
| 395 |
+ ) -> None: |
|
| 396 |
+ runner = click.testing.CliRunner(mix_stderr=False) |
|
| 397 |
+ with tests.isolated_config( |
|
| 398 |
+ monkeypatch=monkeypatch, |
|
| 399 |
+ runner=runner, |
|
| 400 |
+ ): |
|
| 401 |
+ _result = runner.invoke( |
|
| 402 |
+ cli.derivepassphrase_vault, |
|
| 403 |
+ ['--version'], |
|
| 404 |
+ catch_exceptions=False, |
|
| 405 |
+ ) |
|
| 406 |
+ result = tests.ReadableResult.parse(_result) |
|
| 407 |
+ assert result.clean_exit( |
|
| 408 |
+ empty_stderr=True, output=cli.PROG_NAME |
|
| 409 |
+ ), 'expected clean exit, and program name in version text' |
|
| 410 |
+ assert result.clean_exit( |
|
| 411 |
+ empty_stderr=True, output=cli.__version__ |
|
| 412 |
+ ), 'expected clean exit, and version in help text' |
|
| 413 |
+ |
|
| 301 | 414 |
@pytest.mark.parametrize( |
| 302 | 415 |
'charset_name', ['lower', 'upper', 'number', 'space', 'dash', 'symbol'] |
| 303 | 416 |
) |
| 304 | 417 |