Merge pull request #659 from The-Compiler/config-stub

Add a new config_stub fixture.
This commit is contained in:
Florian Bruhin 2015-05-07 22:17:56 +02:00
commit 8837abc208
9 changed files with 159 additions and 150 deletions

View File

@ -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()

View File

@ -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')

View File

@ -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.

View File

@ -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)

View File

@ -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')

View File

@ -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()

View File

@ -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

View File

@ -31,37 +31,6 @@ from PyQt5.QtNetwork import QNetworkRequest
from qutebrowser.config import configexc
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."""
@ -200,11 +169,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:

View File

@ -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')