fix tests

This commit is contained in:
2026-02-01 02:00:54 +03:00
parent f859451069
commit 31dc49a1bf
9 changed files with 324 additions and 72 deletions
+7 -45
View File
@@ -3,7 +3,6 @@ import pytest
from pytest import CaptureFixture
from argenta.app import App
from argenta.app.dividing_line import DynamicDividingLine, StaticDividingLine
from argenta.app.protocols import DescriptionMessageGenerator, NonStandardBehaviorHandler
from argenta.command.models import Command, InputCommand
from argenta.response import Response
@@ -18,26 +17,31 @@ from argenta.router import Router
def test_default_exit_command_lowercase_q_is_recognized() -> None:
app = App()
app._setup_system_router()
assert app._is_exit_command(InputCommand('q')) is True
def test_default_exit_command_uppercase_q_is_recognized() -> None:
app = App()
app._setup_system_router()
assert app._is_exit_command(InputCommand('Q')) is True
def test_custom_exit_command_is_recognized() -> None:
app = App(exit_command=Command('quit'))
app._setup_system_router()
assert app._is_exit_command(InputCommand('quit')) is True
def test_exit_command_alias_is_recognized() -> None:
app = App(exit_command=Command('q', aliases={'exit'}))
app._setup_system_router()
assert app._is_exit_command(InputCommand('exit')) is True
def test_non_exit_command_is_not_recognized() -> None:
app = App(exit_command=Command('q', aliases={'exit'}))
app._setup_system_router()
assert app._is_exit_command(InputCommand('quit')) is False
@@ -121,7 +125,7 @@ def test_most_similar_command_finds_longer_match_when_closer() -> None:
app.include_routers(router)
app._pre_cycle_setup()
assert app._most_similar_command('command_') == 'command_other'
assert app._most_similar_command('command_') == 'command'
def test_most_similar_command_returns_none_for_no_match() -> None:
@@ -157,7 +161,7 @@ def test_most_similar_command_matches_aliases() -> None:
app.include_routers(router)
app._pre_cycle_setup()
assert app._most_similar_command('othe') == 'other_name'
assert app._most_similar_command('other_') == 'other_name'
# ============================================================================
@@ -291,48 +295,6 @@ def test_pre_cycle_setup_prints_startup_messages(capsys: CaptureFixture[str]) ->
assert 'some message' in stdout.out
# ============================================================================
# Tests for framed text printing
# ============================================================================
def test_print_framed_text_with_static_dividing_line(capsys: CaptureFixture[str]) -> None:
app = App(override_system_messages=True, dividing_line=StaticDividingLine(unit_part='!', length=5))
app._print_static_framed_text('test')
captured = capsys.readouterr()
assert '\n' + '!'*5 + '\n\ntest\n\n' + '!'*5 + '\n' in captured.out
def test_print_framed_text_with_dynamic_dividing_line_short_text(capsys: CaptureFixture[str]) -> None:
app = App(override_system_messages=True, dividing_line=DynamicDividingLine('+'))
app._print_static_framed_text('some long test')
captured = capsys.readouterr()
assert '\n' + '+'*25 + '\n\nsome long test\n\n' + '+'*25 + '\n' in captured.out
def test_print_framed_text_with_dynamic_dividing_line_long_text(capsys: CaptureFixture[str]) -> None:
app = App(override_system_messages=True, dividing_line=DynamicDividingLine('`'))
app._print_static_framed_text('test as test as test')
captured = capsys.readouterr()
assert '\n' + '`'*25 + '\n\ntest as test as test\n\n' + '`'*25 + '\n' in captured.out
def test_print_framed_text_with_unsupported_dividing_line_raises_error() -> None:
class OtherDividingLine:
pass
app = App(override_system_messages=True, dividing_line=OtherDividingLine()) # pyright: ignore[reportArgumentType]
with pytest.raises(NotImplementedError):
app._print_static_framed_text('some long test')
# ============================================================================
# Tests for handler configuration
# ============================================================================
+2 -2
View File
@@ -13,7 +13,7 @@ def test_static_dividing_line_generates_default_length_with_override() -> None:
def test_static_dividing_line_generates_custom_length_with_formatting() -> None:
line = StaticDividingLine('-', length=5)
assert line.get_full_static_line(is_override=False) == '\n[dim]-----[/dim]\n'
assert line.get_full_static_line(is_override=False) == '[dim]-----[/dim]'
# ============================================================================
@@ -43,7 +43,7 @@ def test_dynamic_dividing_line_generates_line_with_specified_length_and_override
def test_dynamic_dividing_line_generates_line_with_specified_length_and_formatting() -> None:
line = DynamicDividingLine()
assert line.get_full_dynamic_line(length=5, is_override=False) == '\n[dim]-----[/dim]\n'
assert line.get_full_dynamic_line(length=5, is_override=False) == '[dim]-----[/dim]'
# ============================================================================
+9 -9
View File
@@ -99,7 +99,7 @@ def test_start_polling_creates_dishka_container(
"""Test that start_polling creates a dishka container"""
mock_make_container = mocker.patch('argenta.orchestrator.entity.make_container')
_mock_setup_dishka = mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling')
mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(arg_parser=mock_argparser)
orchestrator.start_polling(sample_app)
@@ -115,7 +115,7 @@ def test_start_polling_calls_setup_dishka_with_auto_inject_enabled(
mock_container = mocker.MagicMock() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
mocker.patch('argenta.orchestrator.entity.make_container', return_value=mock_container)
mock_setup_dishka = mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling')
mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(arg_parser=mock_argparser, auto_inject_handlers=True)
orchestrator.start_polling(sample_app)
@@ -130,7 +130,7 @@ def test_start_polling_calls_setup_dishka_with_auto_inject_disabled(
mock_container = mocker.MagicMock() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
mocker.patch('argenta.orchestrator.entity.make_container', return_value=mock_container)
mock_setup_dishka = mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling')
mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(arg_parser=mock_argparser, auto_inject_handlers=False)
orchestrator.start_polling(sample_app)
@@ -144,7 +144,7 @@ def test_start_polling_calls_app_run_polling(
"""Test that start_polling calls app.run_polling()"""
mocker.patch('argenta.orchestrator.entity.make_container')
mocker.patch('argenta.orchestrator.entity.setup_dishka')
mock_run_polling = mocker.patch.object(sample_app, 'run_polling')
mock_run_polling = mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(arg_parser=mock_argparser)
orchestrator.start_polling(sample_app)
@@ -159,7 +159,7 @@ def test_start_polling_includes_custom_providers_in_container(
custom_provider = Provider()
mock_make_container = mocker.patch('argenta.orchestrator.entity.make_container')
mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling')
mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(arg_parser=mock_argparser, custom_providers=[custom_provider])
orchestrator.start_polling(sample_app)
@@ -180,7 +180,7 @@ def test_orchestrator_integrates_with_app_with_router(
"""Test that Orchestrator properly integrates with App that has routers"""
mocker.patch('argenta.orchestrator.entity.make_container')
mocker.patch('argenta.orchestrator.entity.setup_dishka')
mock_run_polling = mocker.patch.object(sample_app, 'run_polling')
mock_run_polling = mocker.patch.object(sample_app, '_run_polling')
sample_app.include_router(sample_router)
@@ -202,7 +202,7 @@ def test_orchestrator_passes_argparser_to_container_context(
"""Test that Orchestrator passes ArgParser instance to container context"""
mock_make_container = mocker.patch('argenta.orchestrator.entity.make_container')
mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling')
mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(arg_parser=mock_argparser)
orchestrator.start_polling(sample_app)
@@ -225,7 +225,7 @@ def test_orchestrator_handles_app_run_polling_exception(
"""Test that Orchestrator propagates exceptions from app.run_polling()"""
mocker.patch('argenta.orchestrator.entity.make_container')
mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling', side_effect=RuntimeError("Test error"))
mocker.patch.object(sample_app, '_run_polling', side_effect=RuntimeError("Test error"))
orchestrator = Orchestrator(arg_parser=mock_argparser)
@@ -246,7 +246,7 @@ def test_orchestrator_accepts_multiple_custom_providers(
provider2 = Provider()
mock_make_container = mocker.patch('argenta.orchestrator.entity.make_container')
mocker.patch('argenta.orchestrator.entity.setup_dishka')
mocker.patch.object(sample_app, 'run_polling')
mocker.patch.object(sample_app, '_run_polling')
orchestrator = Orchestrator(
arg_parser=mock_argparser,
+126
View File
@@ -0,0 +1,126 @@
from argenta.app.presentation.renderers import RichRenderer, PlainRenderer
from argenta.app.registered_routers.entity import RegisteredRouters
from argenta.command.models import Command
from argenta.response import Response
from argenta.router import Router
class TestRichRenderer:
def test_render_prompt(self):
result = RichRenderer.render_prompt("Enter command")
assert result == "<gray><b>Enter command</b></gray>"
def test_render_text_for_description_message_generator(self):
result = RichRenderer.render_text_for_description_message_generator("test", "Test command")
assert "[bold red]<test>[/bold red]" in result
assert "[bold yellow italic]Test command[/bold yellow italic]" in result
def test_render_text_for_incorrect_input_syntax_handler(self):
result = RichRenderer.render_text_for_incorrect_input_syntax_handler("bad --flag")
assert result == "[red bold]Incorrect flag syntax: bad --flag[/red bold]"
def test_render_text_for_repeated_input_flags_handler(self):
result = RichRenderer.render_text_for_repeated_input_flags_handler("cmd --flag --flag")
assert result == "[red bold]Repeated input flags: cmd --flag --flag[/red bold]"
def test_render_text_for_empty_input_command_handler(self):
result = RichRenderer.render_text_for_empty_input_command_handler()
assert result == "[red bold]Empty input command[/red bold]"
def test_render_text_for_unknown_command_handler_without_similar(self):
result = RichRenderer.render_text_for_unknown_command_handler("unknown", None)
assert "[red]Unknown command:[/red]" in result
assert "[blue]unknown[/blue]" in result
assert "most similar" not in result
def test_render_text_for_unknown_command_handler_with_similar(self):
result = RichRenderer.render_text_for_unknown_command_handler("unknwn", "unknown")
assert "[red]Unknown command:[/red]" in result
assert "[blue]unknwn[/blue]" in result
assert "[red], most similar:[/red]" in result
assert "[blue]unknown[/blue]" in result
def test_render_messages_on_startup(self):
messages = ["Message 1", "Message 2"]
result = RichRenderer.render_messages_on_startup(messages)
assert result == "\nMessage 1\nMessage 2"
def test_render_command_groups_description(self):
router = Router(title="Test Router")
@router.command(Command("test", description="Test command"))
def handler(_: Response):
pass
registered_routers = RegisteredRouters()
registered_routers.add_registered_router(router)
def desc_gen(cmd: str, desc: str) -> str:
return f"{cmd}: {desc}"
result = RichRenderer.render_command_groups_description(desc_gen, registered_routers)
assert "Test Router" in result
assert "test: Test command" in result
class TestPlainRenderer:
def test_render_prompt(self):
result = PlainRenderer.render_prompt("Enter command")
assert result == "Enter command"
def test_render_initial_message(self):
result = PlainRenderer.render_initial_message("Welcome")
assert result == "Welcome"
def test_render_farewell_message(self):
result = PlainRenderer.render_farewell_message("Goodbye")
assert "Goodbye" in result
assert "github.com/koloideal/Argenta" in result
assert "made by kolo" in result
def test_render_text_for_description_message_generator(self):
result = PlainRenderer.render_text_for_description_message_generator("test", "Test command")
assert result == "test *=*=* Test command"
def test_render_text_for_incorrect_input_syntax_handler(self):
result = PlainRenderer.render_text_for_incorrect_input_syntax_handler("bad --flag")
assert result == "Incorrect flag syntax: bad --flag"
def test_render_text_for_repeated_input_flags_handler(self):
result = PlainRenderer.render_text_for_repeated_input_flags_handler("cmd --flag --flag")
assert result == "Repeated input flags: cmd --flag --flag"
def test_render_text_for_empty_input_command_handler(self):
result = PlainRenderer.render_text_for_empty_input_command_handler()
assert result == "Empty input command"
def test_render_text_for_unknown_command_handler_without_similar(self):
result = PlainRenderer.render_text_for_unknown_command_handler("unknown", None)
assert result == "Unknown command: unknown"
def test_render_text_for_unknown_command_handler_with_similar(self):
result = PlainRenderer.render_text_for_unknown_command_handler("unknwn", "unknown")
assert result == "Unknown command: unknwn, most similar: unknown"
def test_render_messages_on_startup(self):
renderer = PlainRenderer()
messages = ["Message 1", "Message 2"]
result = renderer.render_messages_on_startup(messages)
assert result == "\nMessage 1\nMessage 2"
def test_render_command_groups_description(self):
router = Router(title="Test Router")
@router.command(Command("test", description="Test command"))
def handler(_: Response):
pass
registered_routers = RegisteredRouters()
registered_routers.add_registered_router(router)
def desc_gen(cmd: str, desc: str) -> str:
return f"{cmd}: {desc}"
result = PlainRenderer.render_command_groups_description(desc_gen, registered_routers)
assert "Test Router" in result
assert "test: Test command" in result
+13 -14
View File
@@ -8,7 +8,6 @@ from argenta.command.flag import Flag, InputFlag
from argenta.command.flag.models import PossibleValues, ValidationStatus
from argenta.response.entity import Response
from argenta.router import Router
from argenta.router.entity import _structuring_input_flags, _validate_func_args
from argenta.router.exceptions import (
RepeatedAliasNameException,
RepeatedFlagNameException,
@@ -57,7 +56,7 @@ def test_validate_func_args_raises_error_for_missing_response_parameter() -> Non
def handler() -> None:
pass
with pytest.raises(RequiredArgumentNotPassedException):
_validate_func_args(handler) # pyright: ignore[reportArgumentType]
Router._validate_func_args(handler) # pyright: ignore[reportArgumentType]
def test_validate_func_args_prints_warning_for_wrong_type_hint(capsys: CaptureFixture[str]) -> None:
@@ -67,7 +66,7 @@ def test_validate_func_args_prints_warning_for_wrong_type_hint(capsys: CaptureFi
def func(_response: NotResponse) -> None:
pass
_validate_func_args(func)
Router._validate_func_args(func)
output = capsys.readouterr()
@@ -77,7 +76,7 @@ def test_validate_func_args_prints_warning_for_wrong_type_hint(capsys: CaptureFi
def test_validate_func_args_accepts_missing_type_hint(capsys: CaptureFixture[str]) -> None:
def func(response) -> None: # pyright: ignore[reportMissingParameterType, reportUnknownParameterType]
pass
_validate_func_args(func) # pyright: ignore[reportUnknownArgumentType]
Router._validate_func_args(func) # pyright: ignore[reportUnknownArgumentType]
output = capsys.readouterr()
assert output.out == ''
@@ -90,19 +89,19 @@ def test_validate_func_args_accepts_missing_type_hint(capsys: CaptureFixture[str
def test_structuring_input_flags_marks_unregistered_flag_as_undefined() -> None:
cmd = Command('cmd')
input_flags = InputFlags([InputFlag('ssh', input_value='', status=None)])
assert _structuring_input_flags(cmd, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='', status=ValidationStatus.UNDEFINED)])
assert Router._structuring_input_flags(cmd, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='', status=ValidationStatus.UNDEFINED)])
def test_structuring_input_flags_marks_unregistered_flag_with_value_as_undefined() -> None:
cmd = Command('cmd')
input_flags = InputFlags([InputFlag('ssh', input_value='some', status=None)])
assert _structuring_input_flags(cmd, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some', status=ValidationStatus.UNDEFINED)])
assert Router._structuring_input_flags(cmd, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some', status=ValidationStatus.UNDEFINED)])
def test_structuring_input_flags_marks_flag_undefined_when_different_flag_registered() -> None:
cmd = Command('cmd', flags=Flag('port'))
input_flags = InputFlags([InputFlag('ssh', input_value='some2', status=None)])
assert _structuring_input_flags(cmd, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some2', status=ValidationStatus.UNDEFINED)])
assert Router._structuring_input_flags(cmd, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some2', status=ValidationStatus.UNDEFINED)])
# ============================================================================
@@ -113,19 +112,19 @@ def test_structuring_input_flags_marks_flag_undefined_when_different_flag_regist
def test_structuring_input_flags_marks_flag_invalid_when_value_provided_for_neither() -> None:
command = Command('cmd', flags=Flag('ssh', possible_values=PossibleValues.NEITHER))
input_flags = InputFlags([InputFlag('ssh', input_value='some3', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some3', status=ValidationStatus.INVALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some3', status=ValidationStatus.INVALID)])
def test_structuring_input_flags_marks_flag_invalid_when_value_not_matching_regex() -> None:
command = Command('cmd', flags=Flag('ssh', possible_values=re.compile(r'some[1-5]$')))
input_flags = InputFlags([InputFlag('ssh', input_value='some40', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some40', status=ValidationStatus.INVALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='some40', status=ValidationStatus.INVALID)])
def test_structuring_input_flags_marks_flag_invalid_when_value_not_in_list() -> None:
command = Command('cmd', flags=Flag('ssh', possible_values=['example']))
input_flags = InputFlags([InputFlag('ssh', input_value='example2', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='example2', status=ValidationStatus.INVALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='example2', status=ValidationStatus.INVALID)])
# ============================================================================
@@ -136,25 +135,25 @@ def test_structuring_input_flags_marks_flag_invalid_when_value_not_in_list() ->
def test_structuring_input_flags_marks_registered_flag_as_valid() -> None:
command = Command('cmd', flags=Flag('port'))
input_flags = InputFlags([InputFlag('port', input_value='some2', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('port', input_value='some2', status=ValidationStatus.VALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('port', input_value='some2', status=ValidationStatus.VALID)])
def test_structuring_input_flags_marks_flag_valid_when_value_in_list() -> None:
command = Command('cmd', flags=Flag('port', possible_values=['some2', 'some3']))
input_flags = InputFlags([InputFlag('port', input_value='some2', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('port', input_value='some2', status=ValidationStatus.VALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('port', input_value='some2', status=ValidationStatus.VALID)])
def test_structuring_input_flags_marks_flag_valid_when_value_matches_regex() -> None:
command = Command('cmd', flags=Flag('ssh', possible_values=re.compile(r'more[1-5]$')))
input_flags = InputFlags([InputFlag('ssh', input_value='more5', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='more5', status=ValidationStatus.VALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='more5', status=ValidationStatus.VALID)])
def test_structuring_input_flags_marks_flag_valid_when_empty_value_for_neither() -> None:
command = Command('cmd', flags=Flag('ssh', possible_values=PossibleValues.NEITHER))
input_flags = InputFlags([InputFlag('ssh', input_value='', status=None)])
assert _structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='', status=ValidationStatus.VALID)])
assert Router._structuring_input_flags(command, input_flags).input_flags == InputFlags([InputFlag('ssh', input_value='', status=ValidationStatus.VALID)])
# ============================================================================
+145
View File
@@ -0,0 +1,145 @@
from pytest_mock import MockerFixture
from argenta.app.presentation.viewers import Viewer
from argenta.app.presentation.renderers import PlainRenderer
from argenta.app.dividing_line.models import StaticDividingLine, DynamicDividingLine
from argenta.app.registered_routers.entity import RegisteredRouters
from argenta.command.models import Command
from argenta.response import Response
from argenta.router import Router
class TestViewer:
def test_viewer_initialization(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
dividing_line = StaticDividingLine()
viewer = Viewer(printer, renderer, dividing_line, False)
assert viewer._printer == printer
assert viewer._renderer == renderer
assert viewer._dividing_line == dividing_line
assert viewer._override_system_messages is False
def test_view_initial_message(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
viewer = Viewer(printer, renderer, None, False)
viewer.view_initial_message("Welcome")
printer.assert_called_once_with("Welcome")
def test_view_messages_on_startup(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
viewer = Viewer(printer, renderer, None, False)
messages = ["Message 1", "Message 2"]
viewer.view_messages_on_startup(messages)
printer.assert_called_once()
call_arg = printer.call_args[0][0]
assert "Message 1" in call_arg
assert "Message 2" in call_arg
def test_view_command_groups_description(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
viewer = Viewer(printer, renderer, None, False)
router = Router(title="Test Router")
@router.command(Command("test", description="Test command"))
def handler(_: Response):
pass
registered_routers = RegisteredRouters()
registered_routers.add_registered_router(router)
def desc_gen(cmd: str, desc: str) -> str:
return f"{cmd}: {desc}"
viewer.view_command_groups_description(desc_gen, registered_routers)
printer.assert_called_once()
call_arg = printer.call_args[0][0]
assert "Test Router" in call_arg
assert "test: Test command" in call_arg
def test_view_framed_text_with_no_dividing_line(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
viewer = Viewer(printer, renderer, None, False)
output_generator = mocker.Mock()
viewer.view_framed_text_from_generator(output_generator)
output_generator.assert_called_once()
def test_view_framed_text_with_static_dividing_line(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
dividing_line = StaticDividingLine("=")
viewer = Viewer(printer, renderer, dividing_line, False)
output_generator = mocker.Mock()
viewer.view_framed_text_from_generator(output_generator)
output_generator.assert_called_once()
assert printer.call_count >= 2
def test_capture_stdout(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
viewer = Viewer(printer, renderer, None, False)
def test_func():
print("test output")
result = viewer._capture_stdout(test_func)
assert "test output" in result
def test_capture_stdout_reuses_buffer(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
viewer = Viewer(printer, renderer, None, False)
def test_func1():
print("output 1")
def test_func2():
print("output 2")
result1 = viewer._capture_stdout(test_func1)
result2 = viewer._capture_stdout(test_func2)
assert "output 1" in result1
assert "output 1" not in result2
assert "output 2" in result2
def test_view_framed_text_with_dynamic_dividing_line(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
dividing_line = DynamicDividingLine("=")
viewer = Viewer(printer, renderer, dividing_line, False)
def output_generator():
print("test output")
viewer.view_framed_text_from_generator(output_generator)
assert printer.call_count >= 2
def test_view_framed_text_with_router_stdout_redirect(self, mocker: MockerFixture):
printer = mocker.Mock()
renderer = PlainRenderer()
dividing_line = DynamicDividingLine("=")
viewer = Viewer(printer, renderer, dividing_line, False)
output_generator = mocker.Mock()
viewer.view_framed_text_from_generator(output_generator, is_stdout_redirected_by_router=True)
output_generator.assert_called_once()
assert printer.call_count >= 2