# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: # Copyright 2014-2015 Florian Bruhin (The Compiler) # # This file is part of qutebrowser. # # qutebrowser is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # qutebrowser is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . """pytest helper to monkeypatch the message module.""" import logging import collections import pytest from qutebrowser.utils import usertypes Message = collections.namedtuple('Message', ['level', 'win_id', 'text', 'immediate']) Level = usertypes.enum('Level', ('error', 'info', 'warning')) class MessageMock: """Helper object for message_mock. Attributes: _monkeypatch: The pytest monkeypatch fixture. Message: A namedtuple representing a message. 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, monkeypatch, caplog): self._monkeypatch = monkeypatch self._caplog = caplog self.messages = [] def _handle(self, level, win_id, text, immediately=False): log_levels = { Level.error: logging.ERROR, Level.info: logging.INFO, Level.warning: logging.WARNING } log_level = log_levels[level] with self._caplog.at_level(log_level): # needed so we don't fail logging.getLogger('message').log(log_level, text) self.messages.append(Message(level, win_id, text, immediately)) def _handle_error(self, *args, **kwargs): 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. Raises ValueError if there are multiple or no messages. Args: 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 msg = self.messages[0] if level is not None: assert msg.level == level assert msg.win_id == win_id assert msg.immediate == immediate return msg def patch(self, module_path): """Patch message.* in the given module (as a string).""" self._monkeypatch.setattr(module_path + '.error', self._handle_error) self._monkeypatch.setattr(module_path + '.info', self._handle_info) self._monkeypatch.setattr(module_path + '.warning', self._handle_warning) @pytest.fixture def message_mock(monkeypatch, caplog): """Fixture to get a MessageMock.""" return MessageMock(monkeypatch, caplog)