Adjust tests/messagemock

This commit is contained in:
Florian Bruhin 2016-09-15 11:56:46 +02:00
parent f16b96aa28
commit a2254b671c
6 changed files with 46 additions and 98 deletions

View File

@ -23,15 +23,12 @@ import logging
import collections import collections
import pytest import pytest
from PyQt5.QtCore import pyqtSlot
from qutebrowser.utils import usertypes from qutebrowser.utils import usertypes, message
Message = collections.namedtuple('Message', ['level', 'win_id', 'text', Message = collections.namedtuple('Message', ['level', 'text'])
'immediate'])
Level = usertypes.enum('Level', ('error', 'info', 'warning'))
class MessageMock: class MessageMock:
@ -39,70 +36,53 @@ class MessageMock:
"""Helper object for message_mock. """Helper object for message_mock.
Attributes: Attributes:
_monkeypatch: The pytest monkeypatch fixture.
Message: A namedtuple representing a message. Message: A namedtuple representing a message.
messages: A list of Message tuples. messages: A list of Message tuples.
caplog: The pytest-capturelog fixture.
Level: The Level type for easier usage as a fixture.
""" """
Level = Level def __init__(self):
def __init__(self, monkeypatch, caplog):
self._monkeypatch = monkeypatch
self._caplog = caplog
self.messages = [] self.messages = []
def _handle(self, level, win_id, text, immediately=False, *, @pyqtSlot(usertypes.MessageLevel, str)
stack=None): # pylint: disable=unused-variable def _record_message(self, level, text):
log_levels = { log_levels = {
Level.error: logging.ERROR, usertypes.MessageLevel.error: logging.ERROR,
Level.info: logging.INFO, usertypes.MessageLevel.info: logging.INFO,
Level.warning: logging.WARNING usertypes.MessageLevel.warning: logging.WARNING,
} }
log_level = log_levels[level] log_level = log_levels[level]
logging.getLogger('messagemock').log(log_level, text) logging.getLogger('messagemock').log(log_level, text)
self.messages.append(Message(level, win_id, text, immediately)) self.messages.append(Message(level, text))
def _handle_error(self, *args, **kwargs): def getmsg(self, level=None):
self._handle(Level.error, *args, **kwargs)
def _handle_info(self, *args, **kwargs):
self._handle(Level.info, *args, **kwargs)
def _handle_warning(self, *args, **kwargs):
self._handle(Level.warning, *args, **kwargs)
def getmsg(self, level=None, *, win_id=0, immediate=False):
"""Get the only message in self.messages. """Get the only message in self.messages.
Raises ValueError if there are multiple or no messages. Raises ValueError if there are multiple or no messages.
Args: Args:
level: The message level to check against, or None. level: The message level to check against, or None.
win_id: The window id to check against.
immediate: If the message has the immediate flag set.
""" """
assert len(self.messages) == 1 assert len(self.messages) == 1
msg = self.messages[0] msg = self.messages[0]
if level is not None: if level is not None:
assert msg.level == level assert msg.level == level
assert msg.win_id == win_id
assert msg.immediate == immediate
return msg return msg
def patch(self, module_path): def patch(self):
"""Patch message.* in the given module (as a string).""" """Start recording messages."""
self._monkeypatch.setattr(module_path + '.error', self._handle_error) message.global_bridge.show_message.connect(self._record_message)
self._monkeypatch.setattr(module_path + '.info', self._handle_info)
self._monkeypatch.setattr(module_path + '.warning', def unpatch(self):
self._handle_warning) """Stop recording messages."""
message.global_bridge.show_message.disconnect(self._record_message)
@pytest.fixture @pytest.fixture
def message_mock(monkeypatch, caplog): def message_mock():
"""Fixture to get a MessageMock.""" """Fixture to get a MessageMock."""
return MessageMock(monkeypatch, caplog) message.init()
mmock = MessageMock()
mmock.patch()
yield mmock
mmock.unpatch()

View File

@ -68,13 +68,6 @@ def basedir(fake_args):
fake_args.basedir = None fake_args.basedir = None
@pytest.fixture
def adblock_message_mock(message_mock):
"""Customized message_mock for the adblock module."""
message_mock.patch('qutebrowser.browser.adblock.message')
return message_mock
class FakeDownloadItem(QObject): class FakeDownloadItem(QObject):
"""Mock browser.downloads.DownloadItem.""" """Mock browser.downloads.DownloadItem."""
@ -257,8 +250,7 @@ def test_without_datadir(config_stub, tmpdir, monkeypatch, win_registry):
def test_disabled_blocking_update(basedir, config_stub, download_stub, def test_disabled_blocking_update(basedir, config_stub, download_stub,
data_tmpdir, tmpdir, win_registry, data_tmpdir, tmpdir, win_registry):
adblock_message_mock):
"""Ensure no URL is blocked when host blocking is disabled.""" """Ensure no URL is blocked when host blocking is disabled."""
config_stub.data = { config_stub.data = {
'content': { 'content': {
@ -293,8 +285,7 @@ def test_no_blocklist_update(config_stub, download_stub,
def test_successful_update(config_stub, basedir, download_stub, def test_successful_update(config_stub, basedir, download_stub,
data_tmpdir, tmpdir, win_registry, data_tmpdir, tmpdir, win_registry):
adblock_message_mock):
"""Ensure hosts from host-block-lists are blocked after an update.""" """Ensure hosts from host-block-lists are blocked after an update."""
config_stub.data = { config_stub.data = {
'content': { 'content': {
@ -314,8 +305,7 @@ def test_successful_update(config_stub, basedir, download_stub,
def test_failed_dl_update(config_stub, basedir, download_stub, def test_failed_dl_update(config_stub, basedir, download_stub,
data_tmpdir, tmpdir, win_registry, data_tmpdir, tmpdir, win_registry):
adblock_message_mock):
"""One blocklist fails to download. """One blocklist fails to download.
Ensure hosts from this list are not blocked. Ensure hosts from this list are not blocked.

View File

@ -29,12 +29,6 @@ from PyQt5.QtCore import QFileSystemWatcher
from qutebrowser.commands import userscripts from qutebrowser.commands import userscripts
@pytest.fixture(autouse=True)
def guiprocess_message_mock(message_mock):
message_mock.patch('qutebrowser.misc.guiprocess.message')
return message_mock
@pytest.mark.posix @pytest.mark.posix
class TestQtFIFOReader: class TestQtFIFOReader:

View File

@ -30,8 +30,7 @@ from qutebrowser.misc import editor as editormod
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def patch_things(config_stub, message_mock, monkeypatch, stubs): def patch_things(config_stub, monkeypatch, stubs):
message_mock.patch('qutebrowser.misc.editor.message')
monkeypatch.setattr('qutebrowser.misc.editor.guiprocess.QProcess', monkeypatch.setattr('qutebrowser.misc.editor.guiprocess.QProcess',
stubs.fake_qprocess()) stubs.fake_qprocess())
config_stub.data = { config_stub.data = {
@ -130,7 +129,7 @@ class TestFileHandling:
os.chmod(filename, 0o077) os.chmod(filename, 0o077)
editor._proc.finished.emit(0, QProcess.NormalExit) editor._proc.finished.emit(0, QProcess.NormalExit)
assert not os.path.exists(filename) assert not os.path.exists(filename)
msg = message_mock.getmsg(message_mock.Level.error) msg = message_mock.getmsg(usertypes.MessageLevel.error)
assert msg.text.startswith("Failed to read back edited file: ") assert msg.text.startswith("Failed to read back edited file: ")
@pytest.mark.posix @pytest.mark.posix
@ -140,7 +139,7 @@ class TestFileHandling:
monkeypatch.setattr('qutebrowser.misc.editor.tempfile.tempdir', monkeypatch.setattr('qutebrowser.misc.editor.tempfile.tempdir',
str(tmpdir)) str(tmpdir))
editor.edit("") editor.edit("")
msg = message_mock.getmsg(message_mock.Level.error) msg = message_mock.getmsg(usertypes.MessageLevel.error)
assert msg.text.startswith("Failed to create initial file: ") assert msg.text.startswith("Failed to create initial file: ")
assert editor._proc is None assert editor._proc is None

View File

@ -28,12 +28,6 @@ from PyQt5.QtCore import QProcess, QIODevice
from qutebrowser.misc import guiprocess from qutebrowser.misc import guiprocess
@pytest.fixture(autouse=True)
def guiprocess_message_mock(message_mock):
message_mock.patch('qutebrowser.misc.guiprocess.message')
return message_mock
@pytest.fixture() @pytest.fixture()
def proc(qtbot): def proc(qtbot):
"""A fixture providing a GUIProcess and cleaning it up after the test.""" """A fixture providing a GUIProcess and cleaning it up after the test."""
@ -55,18 +49,18 @@ def fake_proc(monkeypatch, stubs):
return p return p
def test_start(proc, qtbot, guiprocess_message_mock, py_proc): def test_start(proc, qtbot, message_mock, py_proc):
"""Test simply starting a process.""" """Test simply starting a process."""
with qtbot.waitSignals([proc.started, proc.finished], timeout=10000, with qtbot.waitSignals([proc.started, proc.finished], timeout=10000,
order='strict'): order='strict'):
argv = py_proc("import sys; print('test'); sys.exit(0)") argv = py_proc("import sys; print('test'); sys.exit(0)")
proc.start(*argv) proc.start(*argv)
assert not guiprocess_message_mock.messages assert not message_mock.messages
assert bytes(proc._proc.readAll()).rstrip() == b'test' assert bytes(proc._proc.readAll()).rstrip() == b'test'
def test_start_verbose(proc, qtbot, guiprocess_message_mock, py_proc): def test_start_verbose(proc, qtbot, message_mock, py_proc):
"""Test starting a process verbosely.""" """Test starting a process verbosely."""
proc.verbose = True proc.verbose = True
@ -75,9 +69,9 @@ def test_start_verbose(proc, qtbot, guiprocess_message_mock, py_proc):
argv = py_proc("import sys; print('test'); sys.exit(0)") argv = py_proc("import sys; print('test'); sys.exit(0)")
proc.start(*argv) proc.start(*argv)
msgs = guiprocess_message_mock.messages msgs = message_mock.messages
assert msgs[0].level == guiprocess_message_mock.Level.info assert msgs[0].level == usertypes.MessageLevel.info
assert msgs[1].level == guiprocess_message_mock.Level.info assert msgs[1].level == usertypes.MessageLevel.info
assert msgs[0].text.startswith("Executing:") assert msgs[0].text.startswith("Executing:")
assert msgs[1].text == "Testprocess exited successfully." assert msgs[1].text == "Testprocess exited successfully."
assert bytes(proc._proc.readAll()).rstrip() == b'test' assert bytes(proc._proc.readAll()).rstrip() == b'test'
@ -127,14 +121,13 @@ def test_start_detached(fake_proc):
fake_proc._proc.startDetached.assert_called_with(*list(argv) + [None]) fake_proc._proc.startDetached.assert_called_with(*list(argv) + [None])
def test_start_detached_error(fake_proc, guiprocess_message_mock): def test_start_detached_error(fake_proc, message_mock):
"""Test starting a detached process with ok=False.""" """Test starting a detached process with ok=False."""
argv = ['foo', 'bar'] argv = ['foo', 'bar']
fake_proc._proc.startDetached.return_value = (False, 0) fake_proc._proc.startDetached.return_value = (False, 0)
fake_proc._proc.error.return_value = "Error message" fake_proc._proc.error.return_value = "Error message"
fake_proc.start_detached(*argv) fake_proc.start_detached(*argv)
msg = guiprocess_message_mock.getmsg(guiprocess_message_mock.Level.error, msg = message_mock.getmsg(usertypes.MessageLevel.error)
immediate=True)
assert msg.text == "Error while spawning testprocess: Error message." assert msg.text == "Error while spawning testprocess: Error message."
@ -178,24 +171,23 @@ def test_start_logging(fake_proc, caplog):
"Executing: does_not_exist arg 'arg with spaces'"] "Executing: does_not_exist arg 'arg with spaces'"]
def test_error(qtbot, proc, caplog, guiprocess_message_mock): def test_error(qtbot, proc, caplog, message_mock):
"""Test the process emitting an error.""" """Test the process emitting an error."""
with caplog.at_level(logging.ERROR, 'message'): with caplog.at_level(logging.ERROR, 'message'):
with qtbot.waitSignal(proc.error, timeout=5000): with qtbot.waitSignal(proc.error, timeout=5000):
proc.start('this_does_not_exist_either', []) proc.start('this_does_not_exist_either', [])
msg = guiprocess_message_mock.getmsg(guiprocess_message_mock.Level.error, msg = message_mock.getmsg(usertypes.MessageLevel.error)
immediate=True)
expected_msg = ("Error while spawning testprocess: The process failed to " expected_msg = ("Error while spawning testprocess: The process failed to "
"start.") "start.")
assert msg.text == expected_msg assert msg.text == expected_msg
def test_exit_unsuccessful(qtbot, proc, guiprocess_message_mock, py_proc): def test_exit_unsuccessful(qtbot, proc, message_mock, py_proc):
with qtbot.waitSignal(proc.finished, timeout=10000): with qtbot.waitSignal(proc.finished, timeout=10000):
proc.start(*py_proc('import sys; sys.exit(1)')) proc.start(*py_proc('import sys; sys.exit(1)'))
msg = guiprocess_message_mock.getmsg(guiprocess_message_mock.Level.error) msg = message_mock.getmsg(usertypes.MessageLevel.error)
assert msg.text == "Testprocess exited with status 1." assert msg.text == "Testprocess exited with status 1."

View File

@ -26,7 +26,7 @@ from PyQt5.QtCore import QUrl
import pytest import pytest
from qutebrowser.commands import cmdexc from qutebrowser.commands import cmdexc
from qutebrowser.utils import utils, urlutils, qtutils from qutebrowser.utils import utils, urlutils, qtutils, usertypes
class FakeDNS: class FakeDNS:
@ -106,13 +106,6 @@ def urlutils_config_stub(config_stub, monkeypatch):
return config_stub return config_stub
@pytest.fixture
def urlutils_message_mock(message_mock):
"""Customized message_mock for the urlutils module."""
message_mock.patch('qutebrowser.utils.urlutils.message')
return message_mock
class TestFuzzyUrl: class TestFuzzyUrl:
"""Tests for urlutils.fuzzy_url().""" """Tests for urlutils.fuzzy_url()."""
@ -419,7 +412,7 @@ def test_qurl_from_user_input(user_input, output):
('', False, False), ('', False, False),
('://', False, True), ('://', False, True),
]) ])
def test_invalid_url_error(urlutils_message_mock, url, valid, has_err_string): def test_invalid_url_error(message_mock, url, valid, has_err_string):
"""Test invalid_url_error(). """Test invalid_url_error().
Args: Args:
@ -432,12 +425,12 @@ def test_invalid_url_error(urlutils_message_mock, url, valid, has_err_string):
if valid: if valid:
with pytest.raises(ValueError): with pytest.raises(ValueError):
urlutils.invalid_url_error(qurl, '') urlutils.invalid_url_error(qurl, '')
assert not urlutils_message_mock.messages assert not message_mock.messages
else: else:
assert bool(qurl.errorString()) == has_err_string assert bool(qurl.errorString()) == has_err_string
urlutils.invalid_url_error(qurl, 'frozzle') urlutils.invalid_url_error(qurl, 'frozzle')
msg = urlutils_message_mock.getmsg(urlutils_message_mock.Level.error) msg = message_mock.getmsg(usertypes.MessageLevel.error)
if has_err_string: if has_err_string:
expected_text = ("Trying to frozzle with invalid URL - " + expected_text = ("Trying to frozzle with invalid URL - " +
qurl.errorString()) qurl.errorString())