diff --git a/tests/console/test_Log.py b/tests/console/test_Log.py index b9bb29533..d1c9dc781 100644 --- a/tests/console/test_Log.py +++ b/tests/console/test_Log.py @@ -1,13 +1,13 @@ import datetime from io import TextIOBase -from pathlib import Path from unittest.mock import MagicMock, PropertyMock import pytest from rich.traceback import Trace import briefcase -from briefcase.console import Log +from briefcase.commands.dev import DevCommand +from briefcase.console import Console, Log from briefcase.exceptions import BriefcaseError TRACEBACK_HEADER = "Traceback (most recent call last)" @@ -29,6 +29,16 @@ def now(monkeypatch): return now +@pytest.fixture +def command(tmp_path) -> DevCommand: + """Provides a mocked DevCommand.""" + command = MagicMock(spec_set=DevCommand(Log(), Console())) + command.base_path = tmp_path + command.command = "dev" + command.tools.os.environ = {} + return command + + def test_capture_stacktrace(): """capture_stacktrace sets Log.stacktrace.""" logger = Log() @@ -62,12 +72,11 @@ def test_capture_stacktrace_for_briefcaseerror(skip_logfile): assert logger.skip_log is skip_logfile -def test_save_log_to_file_do_not_log(): +def test_save_log_to_file_do_not_log(command): """Nothing is done to save log if no command or --log wasn't passed.""" logger = Log() logger.save_log_to_file(command=None) - command = MagicMock() logger.save_log = False logger.save_log_to_file(command=command) command.input.wait_bar.assert_not_called() @@ -76,12 +85,9 @@ def test_save_log_to_file_do_not_log(): assert len(logger.stacktraces) == 0 -def test_save_log_to_file_no_exception(tmp_path): +def test_save_log_to_file_no_exception(command, tmp_path): """Log file contains everything printed to log; env vars are sanitized; no stacktrace if one is not captured.""" - command = MagicMock() - command.base_path = Path(tmp_path) - command.command = "dev" command.tools.os.environ = { "GITHUB_KEY": "super-secret-key", "ANDROID_SDK_ROOT": "/androidsdk", @@ -136,13 +142,8 @@ def test_save_log_to_file_no_exception(tmp_path): assert EXTRA_HEADER not in log_contents -def test_save_log_to_file_with_exception(tmp_path): +def test_save_log_to_file_with_exception(command, tmp_path): """Log file contains exception stacktrace when one is captured.""" - command = MagicMock() - command.base_path = Path(tmp_path) - command.command = "dev" - command.tools.os.environ = {} - logger = Log() logger.save_log = True try: @@ -163,13 +164,8 @@ def test_save_log_to_file_with_exception(tmp_path): assert log_contents.splitlines()[-1].startswith("ZeroDivisionError") -def test_save_log_to_file_with_multiple_exceptions(tmp_path): +def test_save_log_to_file_with_multiple_exceptions(command, tmp_path): """Log file contains exception stacktrace when more than one is captured.""" - command = MagicMock() - command.base_path = Path(tmp_path) - command.command = "dev" - command.tools.os.environ = {} - logger = Log() logger.save_log = True for i in range(1, 5): @@ -194,12 +190,8 @@ def test_save_log_to_file_with_multiple_exceptions(tmp_path): assert log_contents.splitlines()[-1].startswith("ZeroDivisionError") -def test_save_log_to_file_extra(tmp_path): +def test_save_log_to_file_extra(command, tmp_path): """Log file extras are called when the log is written.""" - command = MagicMock() - command.base_path = Path(tmp_path) - command.command = "dev" - logger = Log() logger.save_log = True @@ -226,12 +218,8 @@ def extra3(): assert "Log extra 3" in log_contents -def test_save_log_to_file_extra_interrupted(tmp_path): +def test_save_log_to_file_extra_interrupted(command, tmp_path): """Log file extras can be interrupted by Ctrl-C.""" - command = MagicMock() - command.base_path = Path(tmp_path) - command.command = "dev" - logger = Log() logger.save_log = True @@ -248,15 +236,11 @@ def extra1(): assert log_filepath.stat().st_size == 0 -def test_save_log_to_file_fail_to_make_logs_dir(capsys, monkeypatch, tmp_path): +def test_save_log_to_file_fail_to_make_logs_dir(command, capsys, monkeypatch, tmp_path): """User is informed when the ``logs`` directory cannot be created.""" - command = MagicMock() + # Mock the command's base path such that it: mock_base_path = MagicMock(wraps=tmp_path) command.base_path = mock_base_path - command.command = "dev" - command.tools.os.environ = {} - - # Mock the command's base path such that it: # - returns a mocked filepath for the log file mock_base_path.__str__.return_value = "/asdf/log_filepath" # - returns itself when the "logs" directory and log filename are appended @@ -284,13 +268,8 @@ def test_save_log_to_file_fail_to_make_logs_dir(capsys, monkeypatch, tmp_path): ) -def test_save_log_to_file_fail_to_write_file(capsys, monkeypatch, tmp_path): +def test_save_log_to_file_fail_to_write_file(command, capsys, monkeypatch, tmp_path): """User is informed when the log file cannot be written.""" - command = MagicMock() - command.base_path = tmp_path - command.command = "dev" - command.tools.os.environ = {} - # Mock opening a file that raises PermissionError on write mock_open = MagicMock(spec_set=open) monkeypatch.setattr("builtins.open", mock_open) @@ -318,9 +297,6 @@ def test_save_log_to_file_fail_to_write_file(capsys, monkeypatch, tmp_path): def test_log_with_context(tmp_path, capsys): """Log file can be given a persistent context.""" - command = MagicMock() - command.base_path = Path(tmp_path) - logger = Log(verbosity=2) logger.save_log = False @@ -372,9 +348,6 @@ def test_log_with_context(tmp_path, capsys): def test_log_error_with_context(tmp_path, capsys): """If an exception is raised in a logging context, the context is cleared.""" - command = MagicMock() - command.base_path = Path(tmp_path) - logger = Log(verbosity=2) logger.save_log = False