diff --git a/scripts/dev/check_coverage.py b/scripts/dev/check_coverage.py index 9dd6dc137..85605ac2b 100644 --- a/scripts/dev/check_coverage.py +++ b/scripts/dev/check_coverage.py @@ -41,6 +41,7 @@ PERFECT_FILES = [ 'qutebrowser/browser/webelem.py', 'qutebrowser/browser/network/schemehandler.py', 'qutebrowser/browser/network/filescheme.py', + 'qutebrowser/browser/signalfilter.py', 'qutebrowser/misc/readline.py', 'qutebrowser/misc/split.py', diff --git a/tests/browser/test_signalfilter.py b/tests/browser/test_signalfilter.py new file mode 100644 index 000000000..a68136013 --- /dev/null +++ b/tests/browser/test_signalfilter.py @@ -0,0 +1,134 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 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 . + +"""Tests for browser.signalfilter.""" + +import collections +import logging + +import pytest +from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject + +from qutebrowser.browser import signalfilter +from qutebrowser.utils import objreg + + +class FakeTabbedBrowser: + + def __init__(self): + self.index_of = None + self.current_index = None + + def indexOf(self, _tab): + if self.index_of is None: + raise ValueError("indexOf got called with index_of None!") + elif self.index_of is RuntimeError: + raise RuntimeError + else: + return self.index_of + + def currentIndex(self): + if self.current_index is None: + raise ValueError("currentIndex got called with current_index " + "None!") + return self.current_index + + +class Signaller(QObject): + + signal = pyqtSignal(str) + statusbar_message = pyqtSignal(str) + + filtered_signal = pyqtSignal(str) + cur_statusbar_message = pyqtSignal(str) + + def __init__(self, parent=None): + super().__init__(parent) + self.filtered_signal_arg = None + self.filtered_signal.connect(self.filtered_signal_slot) + + @pyqtSlot(str) + def filtered_signal_slot(self, s): + self.filtered_signal_arg = s + + +Objects = collections.namedtuple('Objects', 'signal_filter, signaller') + + +@pytest.fixture +def objects(): + signal_filter = signalfilter.SignalFilter(0) + tab = None + signaller = Signaller() + signaller.signal.connect( + signal_filter.create(signaller.filtered_signal, tab)) + signaller.statusbar_message.connect( + signal_filter.create(signaller.cur_statusbar_message, tab)) + return Objects(signal_filter=signal_filter, signaller=signaller) + +@pytest.yield_fixture +def tabbed_browser(mocker, win_registry): + tb = FakeTabbedBrowser() + objreg.register('tabbed-browser', tb, scope='window', window=0) + yield tb + objreg.delete('tabbed-browser', scope='window', window=0) + + +@pytest.mark.parametrize('index_of, emitted', [(0, True), (1, False)]) +def test_filtering(objects, tabbed_browser, index_of, emitted): + tabbed_browser.current_index = 0 + tabbed_browser.index_of = index_of + objects.signaller.signal.emit('foo') + if emitted: + assert objects.signaller.filtered_signal_arg == 'foo' + else: + assert objects.signaller.filtered_signal_arg is None + + +@pytest.mark.parametrize('index_of, verb', [(0, 'emitting'), (1, 'ignoring')]) +def test_logging(caplog, objects, tabbed_browser, index_of, verb): + tabbed_browser.current_index = 0 + tabbed_browser.index_of = index_of + + with caplog.atLevel(logging.DEBUG, logger='signals'): + objects.signaller.signal.emit('foo') + + records = caplog.records() + assert len(records) == 1 + expected_msg = "{}: filtered_signal('foo') (tab {})".format(verb, index_of) + assert records[0].msg == expected_msg + + +@pytest.mark.parametrize('index_of', [0, 1]) +def test_no_logging(caplog, objects, tabbed_browser, index_of): + tabbed_browser.current_index = 0 + tabbed_browser.index_of = index_of + + with caplog.atLevel(logging.DEBUG, logger='signals'): + objects.signaller.statusbar_message.emit('foo') + + assert not caplog.records() + + +def test_runtime_error(objects, tabbed_browser): + """Test that there's no crash if indexOf() raises RuntimeError.""" + tabbed_browser.current_index = 0 + tabbed_browser.index_of = RuntimeError + objects.signaller.signal.emit('foo') + assert objects.signaller.filtered_signal_arg is None