Add a new config_stub fixture.
This replaces various other constructs: - The default_config fixture - this means the config values used by test_progress.py are set explicitly and the (rather complex) default config is mocked out. - stubs.ConfigStub which was created by the tests manually before.
This commit is contained in:
parent
7975bd8796
commit
f9876823b8
@ -378,11 +378,11 @@ class TestIsEditable:
|
||||
webelem.config = old_config
|
||||
|
||||
@pytest.fixture
|
||||
def stub_config(self, stubs, mocker):
|
||||
def stubbed_config(self, config_stub, mocker):
|
||||
"""Fixture to create a config stub with an input section."""
|
||||
config = stubs.ConfigStub({'input': {}})
|
||||
mocker.patch('qutebrowser.browser.webelem.config', new=config)
|
||||
return config
|
||||
config_stub.data = {'input': {}}
|
||||
mocker.patch('qutebrowser.browser.webelem.config', new=config_stub)
|
||||
return config_stub
|
||||
|
||||
def test_input_plain(self):
|
||||
"""Test with plain input element."""
|
||||
@ -469,27 +469,27 @@ class TestIsEditable:
|
||||
elem = get_webelem(tagname='textarea', attributes={'readonly': None})
|
||||
assert not elem.is_editable()
|
||||
|
||||
def test_embed_true(self, stub_config):
|
||||
def test_embed_true(self, stubbed_config):
|
||||
"""Test embed-element with insert-mode-on-plugins true."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = True
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = True
|
||||
elem = get_webelem(tagname='embed')
|
||||
assert elem.is_editable()
|
||||
|
||||
def test_applet_true(self, stub_config):
|
||||
def test_applet_true(self, stubbed_config):
|
||||
"""Test applet-element with insert-mode-on-plugins true."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = True
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = True
|
||||
elem = get_webelem(tagname='applet')
|
||||
assert elem.is_editable()
|
||||
|
||||
def test_embed_false(self, stub_config):
|
||||
def test_embed_false(self, stubbed_config):
|
||||
"""Test embed-element with insert-mode-on-plugins false."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = False
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = False
|
||||
elem = get_webelem(tagname='embed')
|
||||
assert not elem.is_editable()
|
||||
|
||||
def test_applet_false(self, stub_config):
|
||||
def test_applet_false(self, stubbed_config):
|
||||
"""Test applet-element with insert-mode-on-plugins false."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = False
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = False
|
||||
elem = get_webelem(tagname='applet')
|
||||
assert not elem.is_editable()
|
||||
|
||||
@ -503,30 +503,30 @@ class TestIsEditable:
|
||||
elem = get_webelem(tagname='object', attributes={'type': 'image/gif'})
|
||||
assert not elem.is_editable()
|
||||
|
||||
def test_object_application(self, stub_config):
|
||||
def test_object_application(self, stubbed_config):
|
||||
"""Test object-element with application type."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = True
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = True
|
||||
elem = get_webelem(tagname='object',
|
||||
attributes={'type': 'application/foo'})
|
||||
assert elem.is_editable()
|
||||
|
||||
def test_object_application_false(self, stub_config):
|
||||
def test_object_application_false(self, stubbed_config):
|
||||
"""Test object-element with application type but not ...-on-plugins."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = False
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = False
|
||||
elem = get_webelem(tagname='object',
|
||||
attributes={'type': 'application/foo'})
|
||||
assert not elem.is_editable()
|
||||
|
||||
def test_object_classid(self, stub_config):
|
||||
def test_object_classid(self, stubbed_config):
|
||||
"""Test object-element with classid."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = True
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = True
|
||||
elem = get_webelem(tagname='object',
|
||||
attributes={'type': 'foo', 'classid': 'foo'})
|
||||
assert elem.is_editable()
|
||||
|
||||
def test_object_classid_false(self, stub_config):
|
||||
def test_object_classid_false(self, stubbed_config):
|
||||
"""Test object-element with classid but not insert-mode-on-plugins."""
|
||||
stub_config.data['input']['insert-mode-on-plugins'] = False
|
||||
stubbed_config.data['input']['insert-mode-on-plugins'] = False
|
||||
elem = get_webelem(tagname='object',
|
||||
attributes={'type': 'foo', 'classid': 'foo'})
|
||||
assert not elem.is_editable()
|
||||
|
@ -24,6 +24,10 @@ import itertools
|
||||
|
||||
import pytest
|
||||
|
||||
import stubs as stubsmod
|
||||
from qutebrowser.config import configexc
|
||||
from qutebrowser.utils import objreg
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def app_and_logging(qapp):
|
||||
@ -38,8 +42,7 @@ def app_and_logging(qapp):
|
||||
@pytest.fixture(scope='session')
|
||||
def stubs():
|
||||
"""Provide access to stub objects useful for testing."""
|
||||
import stubs
|
||||
return stubs
|
||||
return stubsmod
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
@ -147,3 +150,49 @@ def cmdline_test(request):
|
||||
# Import qutebrowser.app so all cmdutils.register decorators get run.
|
||||
import qutebrowser.app # pylint: disable=unused-variable
|
||||
return request.param
|
||||
|
||||
|
||||
class ConfigStub:
|
||||
|
||||
"""Stub for the config module.
|
||||
|
||||
Attributes:
|
||||
data: The config data to return.
|
||||
"""
|
||||
|
||||
def __init__(self, signal):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
signal: The signal to use for self.changed.
|
||||
"""
|
||||
self.data = {}
|
||||
self.changed = signal
|
||||
|
||||
def section(self, name):
|
||||
"""Get a section from the config.
|
||||
|
||||
Args:
|
||||
name: The section name to get.
|
||||
|
||||
Return:
|
||||
The section as dict.
|
||||
"""
|
||||
return self.data[name]
|
||||
|
||||
def get(self, sect, opt):
|
||||
"""Get a value from the config."""
|
||||
data = self.data[sect]
|
||||
try:
|
||||
return data[opt]
|
||||
except KeyError:
|
||||
raise configexc.NoOptionError(opt, sect)
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def config_stub(stubs):
|
||||
"""Fixture which provides a fake config object."""
|
||||
stub = ConfigStub(stubs.FakeSignal())
|
||||
objreg.register('config', stub)
|
||||
yield stub
|
||||
objreg.delete('config')
|
||||
|
@ -189,10 +189,12 @@ class TestKeyChain:
|
||||
self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, None)
|
||||
assert self.kp._keystring == ''
|
||||
|
||||
def test_ambiguous_keychain(self, fake_keyevent_factory, mocker, stubs):
|
||||
def test_ambiguous_keychain(self, fake_keyevent_factory, config_stub,
|
||||
mocker):
|
||||
"""Test ambiguous keychain."""
|
||||
config_stub.data = CONFIG
|
||||
mocker.patch('qutebrowser.keyinput.basekeyparser.config',
|
||||
new=stubs.ConfigStub(CONFIG))
|
||||
new=config_stub)
|
||||
timer = self.kp._ambiguous_timer
|
||||
assert not timer.isActive()
|
||||
# We start with 'a' where the keychain gives us an ambiguous result.
|
||||
|
@ -49,12 +49,13 @@ class TestsNormalKeyParser:
|
||||
# pylint: disable=protected-access
|
||||
|
||||
@pytest.yield_fixture(autouse=True)
|
||||
def setup(self, mocker, stubs):
|
||||
def setup(self, mocker, stubs, config_stub):
|
||||
"""Set up mocks and read the test config."""
|
||||
mocker.patch('qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
new=stubs.FakeTimer)
|
||||
config_stub.data = CONFIG
|
||||
mocker.patch('qutebrowser.keyinput.modeparsers.config',
|
||||
new=stubs.ConfigStub(CONFIG))
|
||||
new=config_stub)
|
||||
|
||||
objreg.register('key-config', fake_keyconfig)
|
||||
self.kp = modeparsers.NormalKeyParser(0)
|
||||
|
@ -1,52 +0,0 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""pytest fixtures and utilities for testing.
|
||||
|
||||
Fixtures defined here will be visible to all test files in this directory and
|
||||
below.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from qutebrowser.config.config import ConfigManager
|
||||
from qutebrowser.utils import objreg
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def default_config():
|
||||
"""
|
||||
Fixture that registers an empty config object into the objreg module.
|
||||
|
||||
Should be used by tests which create widgets that obtain their initial
|
||||
state from the global config object.
|
||||
|
||||
Note:
|
||||
|
||||
If we declare this fixture like this:
|
||||
|
||||
@pytest.yield_fixture(autouse=True)
|
||||
|
||||
Then all tests below this file will have a default config registered
|
||||
and ready for use. Is that desirable?
|
||||
"""
|
||||
config_obj = ConfigManager(configdir=None, fname=None, relaxed=True)
|
||||
objreg.register('config', config_obj)
|
||||
yield config_obj
|
||||
objreg.delete('config')
|
@ -29,8 +29,14 @@ from qutebrowser.mainwindow.statusbar.progress import Progress
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def progress_widget(qtbot, default_config):
|
||||
def progress_widget(qtbot, monkeypatch, config_stub):
|
||||
"""Create a Progress widget and checks its initial state."""
|
||||
config_stub.data = {
|
||||
'colors': {'statusbar.progress.bg': 'black'},
|
||||
'fonts': {},
|
||||
}
|
||||
monkeypatch.setattr(
|
||||
'qutebrowser.mainwindow.statusbar.progress.style.config', config_stub)
|
||||
widget = Progress()
|
||||
qtbot.add_widget(widget)
|
||||
assert not widget.isVisible()
|
||||
|
@ -44,39 +44,47 @@ class TestArg:
|
||||
def setup(self, mocker, stubs):
|
||||
mocker.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
self.config = stubs.ConfigStub()
|
||||
mocker.patch('qutebrowser.misc.editor.config', new=self.config)
|
||||
self.editor = editor.ExternalEditor(0)
|
||||
yield
|
||||
self.editor._cleanup() # pylint: disable=protected-access
|
||||
|
||||
def test_simple_start_args(self):
|
||||
@pytest.fixture
|
||||
def stubbed_config(self, config_stub, mocker):
|
||||
"""Fixture to create a config stub with an input section."""
|
||||
config_stub.data = {'input': {}}
|
||||
mocker.patch('qutebrowser.misc.editor.config', new=config_stub)
|
||||
return config_stub
|
||||
|
||||
def test_simple_start_args(self, stubbed_config):
|
||||
"""Test starting editor without arguments."""
|
||||
self.config.data = {
|
||||
stubbed_config.data = {
|
||||
'general': {'editor': ['bin'], 'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
self.editor._proc.start.assert_called_with("bin", [])
|
||||
|
||||
def test_start_args(self):
|
||||
def test_start_args(self, stubbed_config):
|
||||
"""Test starting editor with static arguments."""
|
||||
self.config.data = {'general': {'editor': ['bin', 'foo', 'bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
stubbed_config.data = {
|
||||
'general': {'editor': ['bin', 'foo', 'bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
self.editor._proc.start.assert_called_with("bin", ["foo", "bar"])
|
||||
|
||||
def test_placeholder(self):
|
||||
def test_placeholder(self, stubbed_config):
|
||||
"""Test starting editor with placeholder argument."""
|
||||
self.config.data = {'general': {'editor': ['bin', 'foo', '{}', 'bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
stubbed_config.data = {
|
||||
'general': {'editor': ['bin', 'foo', '{}', 'bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
filename = self.editor._filename
|
||||
self.editor._proc.start.assert_called_with(
|
||||
"bin", ["foo", filename, "bar"])
|
||||
|
||||
def test_in_arg_placeholder(self):
|
||||
def test_in_arg_placeholder(self, stubbed_config):
|
||||
"""Test starting editor with placeholder argument inside argument."""
|
||||
self.config.data = {'general': {'editor': ['bin', 'foo{}bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
stubbed_config.data = {
|
||||
'general': {'editor': ['bin', 'foo{}bar'],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
self.editor.edit("")
|
||||
self.editor._proc.start.assert_called_with("bin", ["foo{}bar"])
|
||||
|
||||
@ -90,15 +98,14 @@ class TestFileHandling:
|
||||
"""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup(self, mocker, stubs):
|
||||
def setup(self, mocker, stubs, config_stub):
|
||||
mocker.patch('qutebrowser.misc.editor.message',
|
||||
new=stubs.MessageModule())
|
||||
mocker.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
mocker.patch('qutebrowser.misc.editor.config',
|
||||
new=stubs.ConfigStub(
|
||||
{'general': {'editor': [''],
|
||||
'editor-encoding': 'utf-8'}}))
|
||||
config_stub.data = {'general': {'editor': [''],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
mocker.patch('qutebrowser.misc.editor.config', config_stub)
|
||||
self.editor = editor.ExternalEditor(0)
|
||||
|
||||
def test_file_handling_closed_ok(self):
|
||||
@ -140,11 +147,12 @@ class TestModifyTests:
|
||||
"""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup(self, mocker, stubs):
|
||||
def setup(self, mocker, stubs, config_stub):
|
||||
mocker.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
mocker.patch('qutebrowser.misc.editor.config', new=stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}}))
|
||||
config_stub.data = {'general': {'editor': [''],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
mocker.patch('qutebrowser.misc.editor.config', new=config_stub)
|
||||
self.editor = editor.ExternalEditor(0)
|
||||
self.editor.editing_finished = mock.Mock()
|
||||
|
||||
@ -211,13 +219,14 @@ class TestErrorMessage:
|
||||
"""
|
||||
|
||||
@pytest.yield_fixture(autouse=True)
|
||||
def setup(self, mocker, stubs):
|
||||
def setup(self, mocker, stubs, config_stub):
|
||||
mocker.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
mocker.patch('qutebrowser.misc.editor.message',
|
||||
new=stubs.MessageModule())
|
||||
mocker.patch('qutebrowser.misc.editor.config', new=stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}}))
|
||||
config_stub.data = {'general': {'editor': [''],
|
||||
'editor-encoding': 'utf-8'}}
|
||||
mocker.patch('qutebrowser.misc.editor.config', new=config_stub)
|
||||
self.editor = editor.ExternalEditor(0)
|
||||
yield
|
||||
self.editor._cleanup() # pylint: disable=protected-access
|
||||
|
@ -29,37 +29,6 @@ from PyQt5.QtCore import pyqtSignal, QPoint, QProcess, QObject
|
||||
from PyQt5.QtNetwork import QNetworkRequest
|
||||
|
||||
|
||||
class ConfigStub:
|
||||
|
||||
"""Stub for basekeyparser.config.
|
||||
|
||||
Attributes:
|
||||
data: The config data to return.
|
||||
"""
|
||||
|
||||
def __init__(self, data=None):
|
||||
self.data = data or {}
|
||||
|
||||
def section(self, name):
|
||||
"""Get a section from the config.
|
||||
|
||||
Args:
|
||||
name: The section name to get.
|
||||
|
||||
Return:
|
||||
The section as dict.
|
||||
"""
|
||||
return self.data[name]
|
||||
|
||||
def get(self, sect, opt):
|
||||
"""Get a value from the config."""
|
||||
data = self.data[sect]
|
||||
try:
|
||||
return data[opt]
|
||||
except KeyError:
|
||||
raise configexc.NoOptionError(opt, sect)
|
||||
|
||||
|
||||
class FakeKeyEvent:
|
||||
|
||||
"""Fake QKeyPressEvent stub."""
|
||||
@ -198,11 +167,35 @@ class FakeQProcess(mock.Mock):
|
||||
|
||||
class FakeSignal:
|
||||
|
||||
"""Fake pyqtSignal stub which uses a mock to see if it was called."""
|
||||
"""Fake pyqtSignal stub which does nothing."""
|
||||
|
||||
def __init__(self, name='fake'):
|
||||
self.signal = '2{}(int, int)'.format(name)
|
||||
|
||||
def connect(self, slot):
|
||||
"""Connect the signal to a slot.
|
||||
|
||||
Currently does nothing, but could be improved to do some sanity
|
||||
checking on the slot.
|
||||
"""
|
||||
pass
|
||||
|
||||
def disconnect(self, slot=None):
|
||||
"""Disconnect the signal from a slot.
|
||||
|
||||
Currently does nothing, but could be improved to do some sanity
|
||||
checking on the slot and see if it actually got connected.
|
||||
"""
|
||||
pass
|
||||
|
||||
def emit(self, *args):
|
||||
"""Emit the signal.
|
||||
|
||||
Currently does nothing, but could be improved to do type checking based
|
||||
on a signature given to __init__.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class FakeCmdUtils:
|
||||
|
||||
|
@ -27,13 +27,14 @@ import pytest
|
||||
from qutebrowser.utils import urlutils
|
||||
|
||||
|
||||
def get_config_stub(auto_search=True):
|
||||
"""Get a config stub.
|
||||
def init_config_stub(stub, auto_search=True):
|
||||
"""Initialize the given config_stub.
|
||||
|
||||
Args:
|
||||
stub: The ConfigStub provided by the config_stub fixture.
|
||||
auto_search: The value auto-search should have.
|
||||
"""
|
||||
return {
|
||||
stub.data = {
|
||||
'general': {'auto-search': auto_search},
|
||||
'searchengines': {
|
||||
'test': 'http://www.qutebrowser.org/?q={}',
|
||||
@ -80,10 +81,10 @@ class TestSearchUrl:
|
||||
"""Test _get_search_url."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_config(self, stubs, mocker):
|
||||
def mock_config(self, config_stub, mocker):
|
||||
"""Fixture to patch urlutils.config with a stub."""
|
||||
mocker.patch('qutebrowser.utils.urlutils.config',
|
||||
new=stubs.ConfigStub(get_config_stub()))
|
||||
init_config_stub(config_stub)
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', config_stub)
|
||||
|
||||
def test_default_engine(self):
|
||||
"""Test default search engine."""
|
||||
@ -158,24 +159,24 @@ class TestIsUrl:
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize('url', URLS)
|
||||
def test_urls(self, mocker, stubs, url):
|
||||
def test_urls(self, mocker, config_stub, url):
|
||||
"""Test things which are URLs."""
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', new=stubs.ConfigStub(
|
||||
get_config_stub('naive')))
|
||||
init_config_stub(config_stub, 'naive')
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', config_stub)
|
||||
assert urlutils.is_url(url), url
|
||||
|
||||
@pytest.mark.parametrize('url', NOT_URLS)
|
||||
def test_not_urls(self, mocker, stubs, url):
|
||||
def test_not_urls(self, mocker, config_stub, url):
|
||||
"""Test things which are not URLs."""
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', new=stubs.ConfigStub(
|
||||
get_config_stub('naive')))
|
||||
init_config_stub(config_stub, 'naive')
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', config_stub)
|
||||
assert not urlutils.is_url(url), url
|
||||
|
||||
@pytest.mark.parametrize('autosearch', [True, False])
|
||||
def test_search_autosearch(self, mocker, stubs, autosearch):
|
||||
def test_search_autosearch(self, mocker, config_stub, autosearch):
|
||||
"""Test explicit search with auto-search=True."""
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', new=stubs.ConfigStub(
|
||||
get_config_stub(autosearch)))
|
||||
init_config_stub(config_stub, autosearch)
|
||||
mocker.patch('qutebrowser.utils.urlutils.config', config_stub)
|
||||
assert not urlutils.is_url('test foo')
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user