Use some more fixtures for older tests.

This commit is contained in:
Florian Bruhin 2015-12-01 22:40:58 +01:00
parent ad72b26b1a
commit 803398c49b
3 changed files with 151 additions and 132 deletions

View File

@ -23,6 +23,7 @@ import os.path
import configparser import configparser
import types import types
import argparse import argparse
import collections
from unittest import mock from unittest import mock
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject
@ -39,128 +40,132 @@ class TestConfigParser:
"""Test reading of ConfigParser.""" """Test reading of ConfigParser."""
@pytest.fixture(autouse=True) Objects = collections.namedtuple('Objects', ['cp', 'cfg'])
def setup(self):
self.cp = configparser.ConfigParser(interpolation=None, @pytest.fixture
def objects(self):
cp = configparser.ConfigParser(interpolation=None,
comment_prefixes='#') comment_prefixes='#')
self.cp.optionxform = lambda opt: opt # be case-insensitive cp.optionxform = lambda opt: opt # be case-insensitive
self.cfg = config.ConfigManager(None, None) cfg = config.ConfigManager(None, None)
return self.Objects(cp=cp, cfg=cfg)
def test_simple(self): def test_simple(self, objects):
"""Test a simple option which is not transformed.""" """Test a simple option which is not transformed."""
self.cp.read_dict({'general': {'ignore-case': 'false'}}) objects.cp.read_dict({'general': {'ignore-case': 'false'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
assert not self.cfg.get('general', 'ignore-case') assert not objects.cfg.get('general', 'ignore-case')
def test_transformed_section_old(self): def test_transformed_section_old(self, objects):
"""Test a transformed section with the old name.""" """Test a transformed section with the old name."""
self.cp.read_dict({'permissions': {'allow-plugins': 'true'}}) objects.cp.read_dict({'permissions': {'allow-plugins': 'true'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
assert self.cfg.get('content', 'allow-plugins') assert objects.cfg.get('content', 'allow-plugins')
def test_transformed_section_new(self): def test_transformed_section_new(self, objects):
"""Test a transformed section with the new name.""" """Test a transformed section with the new name."""
self.cp.read_dict({'content': {'allow-plugins': 'true'}}) objects.cp.read_dict({'content': {'allow-plugins': 'true'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
assert self.cfg.get('content', 'allow-plugins') assert objects.cfg.get('content', 'allow-plugins')
def test_transformed_option_old(self): def test_transformed_option_old(self, objects):
"""Test a transformed option with the old name.""" """Test a transformed option with the old name."""
# WORKAROUND # WORKAROUND
# Instance of 'object' has no 'name' member (no-member) # Instance of 'object' has no 'name' member (no-member)
# pylint: disable=no-member # pylint: disable=no-member
self.cp.read_dict({'colors': {'tab.fg.odd': 'pink'}}) objects.cp.read_dict({'colors': {'tab.fg.odd': 'pink'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
actual = self.cfg.get('colors', 'tabs.fg.odd').name() actual = objects.cfg.get('colors', 'tabs.fg.odd').name()
expected = QColor('pink').name() expected = QColor('pink').name()
assert actual == expected assert actual == expected
def test_transformed_option_new(self): def test_transformed_option_new(self, objects):
"""Test a transformed section with the new name.""" """Test a transformed section with the new name."""
# WORKAROUND # WORKAROUND
# Instance of 'object' has no 'name' member (no-member) # Instance of 'object' has no 'name' member (no-member)
# pylint: disable=no-member # pylint: disable=no-member
self.cp.read_dict({'colors': {'tabs.fg.odd': 'pink'}}) objects.cp.read_dict({'colors': {'tabs.fg.odd': 'pink'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
actual = self.cfg.get('colors', 'tabs.fg.odd').name() actual = objects.cfg.get('colors', 'tabs.fg.odd').name()
expected = QColor('pink').name() expected = QColor('pink').name()
assert actual == expected assert actual == expected
def test_invalid_value(self): def test_invalid_value(self, objects):
"""Test setting an invalid value.""" """Test setting an invalid value."""
self.cp.read_dict({'general': {'ignore-case': 'invalid'}}) objects.cp.read_dict({'general': {'ignore-case': 'invalid'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
with pytest.raises(configexc.ValidationError): with pytest.raises(configexc.ValidationError):
self.cfg._validate_all() objects.cfg._validate_all()
def test_invalid_value_interpolated(self): def test_invalid_value_interpolated(self, objects):
"""Test setting an invalid interpolated value.""" """Test setting an invalid interpolated value."""
self.cp.read_dict({'general': {'ignore-case': 'smart', objects.cp.read_dict({'general': {'ignore-case': 'smart',
'wrap-search': '${ignore-case}'}}) 'wrap-search': '${ignore-case}'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
with pytest.raises(configexc.ValidationError): with pytest.raises(configexc.ValidationError):
self.cfg._validate_all() objects.cfg._validate_all()
def test_interpolation(self): def test_interpolation(self, objects):
"""Test setting an interpolated value.""" """Test setting an interpolated value."""
self.cp.read_dict({'general': {'ignore-case': 'false', objects.cp.read_dict({'general': {'ignore-case': 'false',
'wrap-search': '${ignore-case}'}}) 'wrap-search': '${ignore-case}'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
assert not self.cfg.get('general', 'ignore-case') assert not objects.cfg.get('general', 'ignore-case')
assert not self.cfg.get('general', 'wrap-search') assert not objects.cfg.get('general', 'wrap-search')
def test_interpolation_cross_section(self): def test_interpolation_cross_section(self, objects):
"""Test setting an interpolated value from another section.""" """Test setting an interpolated value from another section."""
self.cp.read_dict( objects.cp.read_dict(
{ {
'general': {'ignore-case': '${network:do-not-track}'}, 'general': {'ignore-case': '${network:do-not-track}'},
'network': {'do-not-track': 'false'}, 'network': {'do-not-track': 'false'},
} }
) )
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
assert not self.cfg.get('general', 'ignore-case') assert not objects.cfg.get('general', 'ignore-case')
assert not self.cfg.get('network', 'do-not-track') assert not objects.cfg.get('network', 'do-not-track')
def test_invalid_interpolation(self): def test_invalid_interpolation(self, objects):
"""Test an invalid interpolation.""" """Test an invalid interpolation."""
self.cp.read_dict({'general': {'ignore-case': '${foo}'}}) objects.cp.read_dict({'general': {'ignore-case': '${foo}'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
with pytest.raises(configparser.InterpolationError): with pytest.raises(configparser.InterpolationError):
self.cfg._validate_all() objects.cfg._validate_all()
def test_invalid_interpolation_syntax(self): def test_invalid_interpolation_syntax(self, objects):
"""Test an invalid interpolation syntax.""" """Test an invalid interpolation syntax."""
self.cp.read_dict({'general': {'ignore-case': '${'}}) objects.cp.read_dict({'general': {'ignore-case': '${'}})
with pytest.raises(configexc.InterpolationSyntaxError): with pytest.raises(configexc.InterpolationSyntaxError):
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
def test_invalid_section(self): def test_invalid_section(self, objects):
"""Test an invalid section.""" """Test an invalid section."""
self.cp.read_dict({'foo': {'bar': 'baz'}}) objects.cp.read_dict({'foo': {'bar': 'baz'}})
with pytest.raises(configexc.NoSectionError): with pytest.raises(configexc.NoSectionError):
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
def test_invalid_option(self): def test_invalid_option(self, objects):
"""Test an invalid option.""" """Test an invalid option."""
self.cp.read_dict({'general': {'bar': 'baz'}}) objects.cp.read_dict({'general': {'bar': 'baz'}})
with pytest.raises(configexc.NoOptionError): with pytest.raises(configexc.NoOptionError):
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
def test_invalid_section_relaxed(self): def test_invalid_section_relaxed(self, objects):
"""Test an invalid section with relaxed=True.""" """Test an invalid section with relaxed=True."""
self.cp.read_dict({'foo': {'bar': 'baz'}}) objects.cp.read_dict({'foo': {'bar': 'baz'}})
self.cfg._from_cp(self.cp, relaxed=True) objects.cfg._from_cp(objects.cp, relaxed=True)
with pytest.raises(configexc.NoSectionError): with pytest.raises(configexc.NoSectionError):
self.cfg.get('foo', 'bar') # pylint: disable=bad-config-call objects.cfg.get('foo', 'bar') # pylint: disable=bad-config-call
def test_invalid_option_relaxed(self): def test_invalid_option_relaxed(self, objects):
"""Test an invalid option with relaxed=True.""" """Test an invalid option with relaxed=True."""
self.cp.read_dict({'general': {'bar': 'baz'}}) objects.cp.read_dict({'general': {'bar': 'baz'}})
self.cfg._from_cp(self.cp, relaxed=True) objects.cfg._from_cp(objects.cp, relaxed=True)
with pytest.raises(configexc.NoOptionError): with pytest.raises(configexc.NoOptionError):
self.cfg.get('general', 'bar') # pylint: disable=bad-config-call # pylint: disable=bad-config-call
objects.cfg.get('general', 'bar')
def test_fallback(self): def test_fallback(self, objects):
"""Test getting an option with fallback. """Test getting an option with fallback.
This is done during interpolation in later Python 3.4 versions. This is done during interpolation in later Python 3.4 versions.
@ -168,18 +173,18 @@ class TestConfigParser:
See https://github.com/The-Compiler/qutebrowser/issues/968 See https://github.com/The-Compiler/qutebrowser/issues/968
""" """
# pylint: disable=bad-config-call # pylint: disable=bad-config-call
assert self.cfg.get('general', 'blabla', fallback='blub') == 'blub' assert objects.cfg.get('general', 'blabla', fallback='blub') == 'blub'
def test_sectionproxy(self): def test_sectionproxy(self, objects):
"""Test getting an option via the section proxy.""" """Test getting an option via the section proxy."""
self.cp.read_dict({'general': {'ignore-case': 'false'}}) objects.cp.read_dict({'general': {'ignore-case': 'false'}})
self.cfg._from_cp(self.cp) objects.cfg._from_cp(objects.cp)
assert not self.cfg['general'].get('ignore-case') assert not objects.cfg['general'].get('ignore-case')
def test_sectionproxy_keyerror(self): def test_sectionproxy_keyerror(self, objects):
"""Test getting an inexistent option via the section proxy.""" """Test getting an inexistent option via the section proxy."""
with pytest.raises(configexc.NoOptionError): with pytest.raises(configexc.NoOptionError):
self.cfg['general'].get('blahblahblub') objects.cfg['general'].get('blahblahblub')
class TestKeyConfigParser: class TestKeyConfigParser:
@ -295,15 +300,7 @@ class TestConfigInit:
"""Test initializing of the config.""" """Test initializing of the config."""
@pytest.yield_fixture(autouse=True) @pytest.yield_fixture(autouse=True)
def setup(self, tmpdir): def patch(self):
self.conf_path = (tmpdir / 'config').ensure(dir=1)
self.data_path = (tmpdir / 'data').ensure(dir=1)
self.cache_path = (tmpdir / 'cache').ensure(dir=1)
self.env = {
'XDG_CONFIG_HOME': str(self.conf_path),
'XDG_DATA_HOME': str(self.data_path),
'XDG_CACHE_HOME': str(self.cache_path),
}
objreg.register('app', QObject()) objreg.register('app', QObject())
objreg.register('save-manager', mock.MagicMock()) objreg.register('save-manager', mock.MagicMock())
args = argparse.Namespace(relaxed_config=False) args = argparse.Namespace(relaxed_config=False)
@ -313,12 +310,24 @@ class TestConfigInit:
objreg.global_registry.clear() objreg.global_registry.clear()
standarddir._args = old_standarddir_args standarddir._args = old_standarddir_args
def test_config_none(self, monkeypatch): @pytest.fixture
def env(self, tmpdir):
conf_path = (tmpdir / 'config').ensure(dir=1)
data_path = (tmpdir / 'data').ensure(dir=1)
cache_path = (tmpdir / 'cache').ensure(dir=1)
env = {
'XDG_CONFIG_HOME': str(conf_path),
'XDG_DATA_HOME': str(data_path),
'XDG_CACHE_HOME': str(cache_path),
}
return env
def test_config_none(self, monkeypatch, env):
"""Test initializing with config path set to None.""" """Test initializing with config path set to None."""
args = types.SimpleNamespace(confdir='', datadir='', cachedir='', args = types.SimpleNamespace(confdir='', datadir='', cachedir='',
basedir=None) basedir=None)
for k, v in self.env.items(): for k, v in env.items():
monkeypatch.setenv(k, v) monkeypatch.setenv(k, v)
standarddir.init(args) standarddir.init(args)
config.init() config.init()
assert not os.listdir(str(self.conf_path)) assert not os.listdir(env['XDG_CONFIG_HOME'])

View File

@ -39,8 +39,8 @@ class TestsNormalKeyParser:
kp: The NormalKeyParser to be tested. kp: The NormalKeyParser to be tested.
""" """
@pytest.yield_fixture(autouse=True) @pytest.fixture(autouse=True)
def setup(self, monkeypatch, stubs, config_stub, fake_keyconfig): def patch_stuff(self, monkeypatch, stubs, config_stub, fake_keyconfig):
"""Set up mocks and read the test config.""" """Set up mocks and read the test config."""
monkeypatch.setattr( monkeypatch.setattr(
'qutebrowser.keyinput.basekeyparser.usertypes.Timer', 'qutebrowser.keyinput.basekeyparser.usertypes.Timer',
@ -49,37 +49,40 @@ class TestsNormalKeyParser:
monkeypatch.setattr('qutebrowser.keyinput.modeparsers.config', monkeypatch.setattr('qutebrowser.keyinput.modeparsers.config',
config_stub) config_stub)
self.kp = modeparsers.NormalKeyParser(0) @pytest.fixture
self.kp.execute = mock.Mock() def keyparser(self):
yield kp = modeparsers.NormalKeyParser(0)
kp.execute = mock.Mock()
return kp
def test_keychain(self, fake_keyevent_factory): def test_keychain(self, keyparser, fake_keyevent_factory):
"""Test valid keychain.""" """Test valid keychain."""
# Press 'x' which is ignored because of no match # Press 'x' which is ignored because of no match
self.kp.handle(fake_keyevent_factory(Qt.Key_X, text='x')) keyparser.handle(fake_keyevent_factory(Qt.Key_X, text='x'))
# Then start the real chain # Then start the real chain
self.kp.handle(fake_keyevent_factory(Qt.Key_B, text='b')) keyparser.handle(fake_keyevent_factory(Qt.Key_B, text='b'))
self.kp.handle(fake_keyevent_factory(Qt.Key_A, text='a')) keyparser.handle(fake_keyevent_factory(Qt.Key_A, text='a'))
self.kp.execute.assert_called_once_with('ba', self.kp.Type.chain, None) keyparser.execute.assert_called_once_with('ba', keyparser.Type.chain,
assert self.kp._keystring == '' None)
assert keyparser._keystring == ''
def test_partial_keychain_timeout(self, fake_keyevent_factory): def test_partial_keychain_timeout(self, keyparser, fake_keyevent_factory):
"""Test partial keychain timeout.""" """Test partial keychain timeout."""
timer = self.kp._partial_timer timer = keyparser._partial_timer
assert not timer.isActive() assert not timer.isActive()
# Press 'b' for a partial match. # Press 'b' for a partial match.
# Then we check if the timer has been set up correctly # Then we check if the timer has been set up correctly
self.kp.handle(fake_keyevent_factory(Qt.Key_B, text='b')) keyparser.handle(fake_keyevent_factory(Qt.Key_B, text='b'))
assert timer.isSingleShot() assert timer.isSingleShot()
assert timer.interval() == 100 assert timer.interval() == 100
assert timer.isActive() assert timer.isActive()
assert not self.kp.execute.called assert not keyparser.execute.called
assert self.kp._keystring == 'b' assert keyparser._keystring == 'b'
# Now simulate a timeout and check the keystring has been cleared. # Now simulate a timeout and check the keystring has been cleared.
keystring_updated_mock = mock.Mock() keystring_updated_mock = mock.Mock()
self.kp.keystring_updated.connect(keystring_updated_mock) keyparser.keystring_updated.connect(keystring_updated_mock)
timer.timeout.emit() timer.timeout.emit()
assert not self.kp.execute.called assert not keyparser.execute.called
assert self.kp._keystring == '' assert keyparser._keystring == ''
keystring_updated_mock.assert_called_once_with('') keystring_updated_mock.assert_called_once_with('')

View File

@ -26,6 +26,7 @@ import os.path
import io import io
import logging import logging
import functools import functools
import collections
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor from PyQt5.QtGui import QColor
@ -259,56 +260,62 @@ class TestInterpolateColor:
white: The Color black as a valid Color for tests. white: The Color black as a valid Color for tests.
""" """
@pytest.fixture(autouse=True) Colors = collections.namedtuple('Colors', ['white', 'black'])
def setup(self):
self.white = Color('white')
self.black = Color('black')
def test_invalid_start(self): @pytest.fixture
def colors(self):
"""Example colors to be used."""
return self.Colors(Color('white'), Color('black'))
def test_invalid_start(self, colors):
"""Test an invalid start color.""" """Test an invalid start color."""
with pytest.raises(qtutils.QtValueError): with pytest.raises(qtutils.QtValueError):
utils.interpolate_color(Color(), self.white, 0) utils.interpolate_color(Color(), colors.white, 0)
def test_invalid_end(self): def test_invalid_end(self, colors):
"""Test an invalid end color.""" """Test an invalid end color."""
with pytest.raises(qtutils.QtValueError): with pytest.raises(qtutils.QtValueError):
utils.interpolate_color(self.white, Color(), 0) utils.interpolate_color(colors.white, Color(), 0)
def test_invalid_percentage(self): def test_invalid_percentage(self, colors):
"""Test an invalid percentage.""" """Test an invalid percentage."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
utils.interpolate_color(self.white, self.white, -1) utils.interpolate_color(colors.white, colors.white, -1)
with pytest.raises(ValueError): with pytest.raises(ValueError):
utils.interpolate_color(self.white, self.white, 101) utils.interpolate_color(colors.white, colors.white, 101)
def test_invalid_colorspace(self): def test_invalid_colorspace(self, colors):
"""Test an invalid colorspace.""" """Test an invalid colorspace."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
utils.interpolate_color(self.white, self.black, 10, QColor.Cmyk) utils.interpolate_color(colors.white, colors.black, 10,
QColor.Cmyk)
def test_valid_percentages_rgb(self): def test_valid_percentages_rgb(self, colors):
"""Test 0% and 100% in the RGB colorspace.""" """Test 0% and 100% in the RGB colorspace."""
white = utils.interpolate_color(self.white, self.black, 0, QColor.Rgb) white = utils.interpolate_color(colors.white, colors.black, 0,
black = utils.interpolate_color(self.white, self.black, 100,
QColor.Rgb) QColor.Rgb)
assert Color(white) == self.white black = utils.interpolate_color(colors.white, colors.black, 100,
assert Color(black) == self.black QColor.Rgb)
assert Color(white) == colors.white
assert Color(black) == colors.black
def test_valid_percentages_hsv(self): def test_valid_percentages_hsv(self, colors):
"""Test 0% and 100% in the HSV colorspace.""" """Test 0% and 100% in the HSV colorspace."""
white = utils.interpolate_color(self.white, self.black, 0, QColor.Hsv) white = utils.interpolate_color(colors.white, colors.black, 0,
black = utils.interpolate_color(self.white, self.black, 100,
QColor.Hsv) QColor.Hsv)
assert Color(white) == self.white black = utils.interpolate_color(colors.white, colors.black, 100,
assert Color(black) == self.black QColor.Hsv)
assert Color(white) == colors.white
assert Color(black) == colors.black
def test_valid_percentages_hsl(self): def test_valid_percentages_hsl(self, colors):
"""Test 0% and 100% in the HSL colorspace.""" """Test 0% and 100% in the HSL colorspace."""
white = utils.interpolate_color(self.white, self.black, 0, QColor.Hsl) white = utils.interpolate_color(colors.white, colors.black, 0,
black = utils.interpolate_color(self.white, self.black, 100,
QColor.Hsl) QColor.Hsl)
assert Color(white) == self.white black = utils.interpolate_color(colors.white, colors.black, 100,
assert Color(black) == self.black QColor.Hsl)
assert Color(white) == colors.white
assert Color(black) == colors.black
def test_interpolation_rgb(self): def test_interpolation_rgb(self):
"""Test an interpolation in the RGB colorspace.""" """Test an interpolation in the RGB colorspace."""