Clean up tests

This commit is contained in:
Florian Bruhin 2014-06-23 19:44:21 +02:00
parent fa95c24d7d
commit 2065f17cb5
15 changed files with 377 additions and 385 deletions

View File

@ -21,7 +21,8 @@ disable=no-self-use,
bad-option-value, bad-option-value,
bad-continuation, bad-continuation,
too-many-instance-attributes, too-many-instance-attributes,
unnecessary-lambda unnecessary-lambda,
blacklisted-name
[BASIC] [BASIC]
module-rgx=(__)?[a-z][a-z0-9_]*(__)?$ module-rgx=(__)?[a-z][a-z0-9_]*(__)?$
@ -33,7 +34,6 @@ argument-rgx=[a-z_][a-z0-9_]{0,30}$
variable-rgx=[a-z_][a-z0-9_]{0,30}$ variable-rgx=[a-z_][a-z0-9_]{0,30}$
class-attribute-rgx=[A-Za-z_][A-Za-z0-9_]{1,30}$ class-attribute-rgx=[A-Za-z_][A-Za-z0-9_]{1,30}$
inlinevar-rgx=[a-z_][a-z0-9_]*$ inlinevar-rgx=[a-z_][a-z0-9_]*$
bad-names=foo,tmp
[FORMAT] [FORMAT]
max-line-length=79 max-line-length=79

View File

@ -17,19 +17,25 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring
"""Tests for BaseKeyParser.""" """Tests for BaseKeyParser."""
import unittest import unittest
import logging import logging
from unittest import TestCase
from unittest.mock import Mock from unittest.mock import Mock
import qutebrowser.keyinput.basekeyparser as basekeyparser import qutebrowser.keyinput.basekeyparser as basekeyparser
from qutebrowser.test.stubs import ConfigStub, FakeKeyEvent
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
CONFIG = {'test': {'<Ctrl-a>': 'ctrla',
'a': 'a',
'ba': 'ba',
'ax': 'ax',
'ccc': 'ccc'},
'input': {'timeout': 100},
'test2': {'foo': 'bar', '<Ctrl+X>': 'ctrlx'}}
def setUpModule(): def setUpModule():
"""Mock out some imports in basekeyparser.""" """Mock out some imports in basekeyparser."""
@ -37,54 +43,7 @@ def setUpModule():
logging.disable(logging.ERROR) logging.disable(logging.ERROR)
class ConfigStub: class NormalizeTests(unittest.TestCase):
"""Stub for basekeyparser.config.
Class attributes:
DATA: The config data to return.
"""
DATA = {'test': {'<Ctrl-a>': 'ctrla',
'a': 'a',
'ba': 'ba',
'ax': 'ax',
'ccc': 'ccc'},
'input': {'timeout': 100},
'test2': {'foo': 'bar', '<Ctrl+X>': 'ctrlx'}}
def section(self, name):
"""Get a section from the config.
Args:
name: The section name to get.
Raise:
ValueError if section isn't test1/test2.
Return:
The section as dict.
"""
if name not in ('test', 'test2'):
raise ValueError("section called with section '{}'!".format(name))
return self.DATA[name]
def get(self, sect, opt):
"""Get a value from the config."""
return self.DATA[sect][opt]
class FakeKeyEvent:
"""Fake QKeyPressEvent stub."""
def __init__(self, key, modifiers=0, text=''):
self.key = Mock(return_value=key)
self.text = Mock(return_value=text)
self.modifiers = Mock(return_value=modifiers)
class NormalizeTests(TestCase):
"""Test _normalize_keystr method.""" """Test _normalize_keystr method."""
@ -105,7 +64,7 @@ class NormalizeTests(TestCase):
self.assertEqual(self.kp._normalize_keystr(orig), repl, orig) self.assertEqual(self.kp._normalize_keystr(orig), repl, orig)
class SplitCountTests(TestCase): class SplitCountTests(unittest.TestCase):
"""Test the _split_count method. """Test the _split_count method.
@ -148,12 +107,12 @@ class SplitCountTests(TestCase):
self.assertEqual(self.kp._split_count(), (None, '10foo')) self.assertEqual(self.kp._split_count(), (None, '10foo'))
class ReadConfigTests(TestCase): class ReadConfigTests(unittest.TestCase):
"""Test reading the config.""" """Test reading the config."""
def setUp(self): def setUp(self):
basekeyparser.config = ConfigStub() basekeyparser.config = ConfigStub(CONFIG)
basekeyparser.QTimer = Mock() basekeyparser.QTimer = Mock()
def test_read_config_invalid(self): def test_read_config_invalid(self):
@ -176,7 +135,7 @@ class ReadConfigTests(TestCase):
self.assertIn('Ctrl+X', kp.special_bindings) self.assertIn('Ctrl+X', kp.special_bindings)
class SpecialKeysTests(TestCase): class SpecialKeysTests(unittest.TestCase):
"""Check execute() with special keys. """Check execute() with special keys.
@ -185,7 +144,7 @@ class SpecialKeysTests(TestCase):
""" """
def setUp(self): def setUp(self):
basekeyparser.config = ConfigStub() basekeyparser.config = ConfigStub(CONFIG)
basekeyparser.QTimer = Mock() basekeyparser.QTimer = Mock()
self.kp = basekeyparser.BaseKeyParser() self.kp = basekeyparser.BaseKeyParser()
self.kp.execute = Mock() self.kp.execute = Mock()
@ -210,7 +169,7 @@ class SpecialKeysTests(TestCase):
self.assertFalse(self.kp.execute.called) self.assertFalse(self.kp.execute.called)
class KeyChainTests(TestCase): class KeyChainTests(unittest.TestCase):
"""Test execute() with keychain support. """Test execute() with keychain support.
@ -221,7 +180,7 @@ class KeyChainTests(TestCase):
def setUp(self): def setUp(self):
"""Set up mocks and read the test config.""" """Set up mocks and read the test config."""
basekeyparser.config = ConfigStub() basekeyparser.config = ConfigStub(CONFIG)
self.timermock = Mock() self.timermock = Mock()
basekeyparser.QTimer = Mock(return_value=self.timermock) basekeyparser.QTimer = Mock(return_value=self.timermock)
self.kp = basekeyparser.BaseKeyParser(supports_chains=True, self.kp = basekeyparser.BaseKeyParser(supports_chains=True,
@ -279,12 +238,12 @@ class KeyChainTests(TestCase):
self.assertEqual(self.kp._keystring, '') self.assertEqual(self.kp._keystring, '')
class CountTests(TestCase): class CountTests(unittest.TestCase):
"""Test execute() with counts.""" """Test execute() with counts."""
def setUp(self): def setUp(self):
basekeyparser.config = ConfigStub() basekeyparser.config = ConfigStub(CONFIG)
basekeyparser.QTimer = Mock() basekeyparser.QTimer = Mock()
self.kp = basekeyparser.BaseKeyParser(supports_chains=True, self.kp = basekeyparser.BaseKeyParser(supports_chains=True,
supports_count=True) supports_count=True)

258
qutebrowser/test/stubs.py Normal file
View File

@ -0,0 +1,258 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014 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/>.
# pylint: disable=invalid-name
"""Fake objects/stubs."""
from unittest.mock import Mock
from PyQt5.QtCore import QPoint, QProcess
from PyQt5.QtWebKit import QWebElement
class ConfigStub:
"""Stub for basekeyparser.config.
Attributes:
data: The config data to return.
"""
class NoOptionError(Exception):
"""NoOptionError exception."""
pass
def __init__(self, data):
self.data = data
def section(self, name):
"""Get a section from the config.
Args:
name: The section name to get.
Raise:
ValueError if section isn't test1/test2.
Return:
The section as dict.
"""
return self.data[name]
def get(self, sect, opt):
"""Get a value from the config."""
sect = self.data[sect]
try:
return sect[opt]
except KeyError:
raise self.NoOptionError
class FakeKeyEvent:
"""Fake QKeyPressEvent stub."""
def __init__(self, key, modifiers=0, text=''):
self.key = Mock(return_value=key)
self.text = Mock(return_value=text)
self.modifiers = Mock(return_value=modifiers)
class FakeWebElement:
"""A stub for QWebElement."""
def __init__(self, geometry=None, frame=None, null=False, visibility='',
display='', attributes=None):
"""Constructor.
Args:
geometry: The geometry of the QWebElement as QRect.
frame: The QWebFrame the element is in.
null: Whether the element is null or not.
visibility: The CSS visibility style property calue.
display: The CSS display style property calue.
attributes: Boolean HTML attributes to be added.
Raise:
ValueError if element is not null and geometry/frame are not given.
"""
self.geometry = Mock(return_value=geometry)
self.webFrame = Mock(return_value=frame)
self.isNull = Mock(return_value=null)
self._visibility = visibility
self._display = display
self._attributes = attributes
def styleProperty(self, name, strategy):
"""Return the CSS style property named name.
Only display/visibility and ComputedStyle are simulated.
Raise:
ValueError if strategy is not ComputedStyle or name is not
visibility/display.
"""
if strategy != QWebElement.ComputedStyle:
raise ValueError("styleProperty called with strategy != "
"ComputedStyle ({})!".format(strategy))
if name == 'visibility':
return self._visibility
elif name == 'display':
return self._display
else:
raise ValueError("styleProperty called with unknown name "
"'{}'".format(name))
def hasAttribute(self, name):
"""Check if the element has an attribute named name."""
if self._attributes is None:
return False
else:
return name in self._attributes
class FakeWebFrame:
"""A stub for QWebFrame."""
def __init__(self, geometry, scroll=None, parent=None):
"""Constructor.
Args:
geometry: The geometry of the frame as QRect.
scroll: The scroll position as QPoint.
parent: The parent frame.
"""
if scroll is None:
scroll = QPoint(0, 0)
self.geometry = Mock(return_value=geometry)
self.scrollPosition = Mock(return_value=scroll)
self.parentFrame = Mock(return_value=parent)
class FakeChildrenFrame:
"""A stub for QWebFrame to test get_child_frames."""
def __init__(self, children=None):
if children is None:
children = []
self.childFrames = Mock(return_value=children)
class FakeQApplication:
"""Stub to insert as QApplication module."""
def __init__(self, focus):
# pylint: disable=invalid-name
self.focusWidget = Mock(return_value=focus)
self.instance = Mock(return_value=self)
class FakeUrl:
"""QUrl stub which provides .path()."""
def __init__(self, path=None):
self.path = Mock(return_value=path)
class FakeNetworkReply:
"""QNetworkReply stub which provides a Content-Disposition header."""
def __init__(self, content_disposition=None, url=None):
if url is None:
url = FakeUrl()
self._content_disposition = content_disposition
self.url = Mock(return_value=url)
def hasRawHeader(self, name):
"""Check if the reply has a certain header.
Args:
name: The name of the header.
Return:
True if the header is present, False if not.
Raise:
ValueError: If a header other than Content-Disposition is
requested.
"""
if name == 'Content-Disposition':
return self._content_disposition is not None
else:
raise ValueError("Invalid header {}".format(name))
def rawHeader(self, name):
"""Get the raw header data of a header.
Args:
name: The name of the header.
Return:
The header data, as ISO-8859-1 encoded bytes() object.
Raise:
ValueError: If a header other than Content-Disposition is
requested.
"""
if name != 'Content-Disposition':
raise ValueError("Invalid header {}".format(name))
cd = self._content_disposition
if cd is None:
raise ValueError("Content-Disposition is None!")
return cd.encode('iso-8859-1')
class FakeQProcess:
"""QProcess stub.
Gets some enum values from the real QProcess and uses mocks for signals.
"""
NormalExit = QProcess.NormalExit
CrashExit = QProcess.CrashExit
FailedToStart = QProcess.FailedToStart
Crashed = QProcess.Crashed
Timedout = QProcess.Timedout
WriteError = QProcess.WriteError
ReadError = QProcess.ReadError
UnknownError = QProcess.UnknownError
def __init__(self, parent=None): # pylint: disable=unused-argument
self.finished = Mock()
self.error = Mock()
self.start = Mock()
class FakeSignal:
"""Fake pyqtSignal stub which uses a mock to see if it was called."""
def __init__(self, name='fake'):
self.signal = '2{}(int, int)'.format(name)

View File

@ -22,12 +22,12 @@
"""Test test helpers.""" """Test test helpers."""
import os import os
from unittest import TestCase import unittest
from qutebrowser.test.helpers import environ_set_temp from qutebrowser.test.helpers import environ_set_temp
class TestEnvironSetTemp(TestCase): class TestEnvironSetTemp(unittest.TestCase):
"""Test the environ_set_temp helper.""" """Test the environ_set_temp helper."""
@ -48,3 +48,6 @@ class TestEnvironSetTemp(TestCase):
if 'QUTEBROWSER_ENVIRON_TEST' in os.environ: if 'QUTEBROWSER_ENVIRON_TEST' in os.environ:
# if some test failed # if some test failed
del os.environ['QUTEBROWSER_ENVIRON_TEST'] del os.environ['QUTEBROWSER_ENVIRON_TEST']
if __name__ == '__main__':
unittest.main()

View File

@ -15,45 +15,37 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=pointless-statement,no-member
"""Tests for qutebrowser.utils.debug.""" """Tests for qutebrowser.utils.debug."""
import unittest import unittest
from unittest import TestCase
from PyQt5.QtWidgets import QStyle, QFrame from PyQt5.QtWidgets import QStyle, QFrame
import qutebrowser.utils.debug as debug import qutebrowser.utils.debug as debug
from qutebrowser.test.stubs import FakeSignal
class FakeSignal: class QEnumKeyTests(unittest.TestCase):
"""Fake pyqtSignal stub which uses a mock to see if it was called."""
def __init__(self, name='fake'):
self.signal = '2{}(int, int)'.format(name)
class QEnumKeyTests(TestCase):
"""Tests for qenum_key.""" """Tests for qenum_key."""
def test_no_metaobj(self): def test_no_metaobj(self):
"""Test with an enum with no metaobject.""" """Test with an enum with no metaobject."""
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
# pylint: disable=pointless-statement,no-member
QStyle.PrimitiveElement.staticMetaObject QStyle.PrimitiveElement.staticMetaObject
key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand) key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand)
self.assertEqual(key, 'PE_PanelButtonCommand') self.assertEqual(key, 'PE_PanelButtonCommand')
def test_metaobj(self): def test_metaobj(self):
"""Test with an enum with metaobject.""" """Test with an enum with metaobject."""
# pylint: disable=pointless-statement
QFrame.staticMetaObject QFrame.staticMetaObject
key = debug.qenum_key(QFrame, QFrame.Sunken) key = debug.qenum_key(QFrame, QFrame.Sunken)
self.assertEqual(key, 'Sunken') self.assertEqual(key, 'Sunken')
class TestDebug(TestCase): class TestDebug(unittest.TestCase):
"""Test signal debug output functions.""" """Test signal debug output functions."""

View File

@ -17,61 +17,17 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=maybe-no-member
"""Tests for qutebrowser.utils.editor.""" """Tests for qutebrowser.utils.editor."""
import os import os
import os.path import os.path
import unittest import unittest
from unittest import TestCase
from unittest.mock import Mock from unittest.mock import Mock
from PyQt5.QtCore import QProcess from PyQt5.QtCore import QProcess
import qutebrowser.utils.editor as editorutils import qutebrowser.utils.editor as editorutils
from qutebrowser.test.stubs import ConfigStub, FakeQProcess
class ConfigStub:
"""Stub for editor.config.
Attributes:
editor: The editor to return for general -> editor.
"""
def __init__(self, editor):
self.editor = editor
def get(self, sect, opt):
"""Get the configured value for sect/opt."""
if sect == 'general' and opt == 'editor':
return self.editor
else:
raise ValueError("Invalid option {} -> {}".format(sect, opt))
class FakeQProcess:
"""QProcess stub.
Gets some enum values from the real QProcess and uses mocks for signals.
"""
NormalExit = QProcess.NormalExit
CrashExit = QProcess.CrashExit
FailedToStart = QProcess.FailedToStart
Crashed = QProcess.Crashed
Timedout = QProcess.Timedout
WriteError = QProcess.WriteError
ReadError = QProcess.ReadError
UnknownError = QProcess.UnknownError
def __init__(self, parent=None): # pylint: disable=unused-argument
self.finished = Mock()
self.error = Mock()
self.start = Mock()
def setUpModule(): def setUpModule():
@ -81,7 +37,7 @@ def setUpModule():
editorutils.QProcess = FakeQProcess editorutils.QProcess = FakeQProcess
class ArgTests(TestCase): class ArgTests(unittest.TestCase):
"""Test argument handling. """Test argument handling.
@ -94,19 +50,21 @@ class ArgTests(TestCase):
def test_simple_start_args(self): def test_simple_start_args(self):
"""Test starting editor without arguments.""" """Test starting editor without arguments."""
editorutils.config = ConfigStub(editor=["bin"]) editorutils.config = ConfigStub({'general': {'editor': ['bin']}})
self.editor.edit("") self.editor.edit("")
self.editor.proc.start.assert_called_with("bin", []) self.editor.proc.start.assert_called_with("bin", [])
def test_start_args(self): def test_start_args(self):
"""Test starting editor with static arguments.""" """Test starting editor with static arguments."""
editorutils.config = ConfigStub(editor=["bin", "foo", "bar"]) editorutils.config = ConfigStub(
{'general': {'editor': ['bin', 'foo', 'bar']}})
self.editor.edit("") self.editor.edit("")
self.editor.proc.start.assert_called_with("bin", ["foo", "bar"]) self.editor.proc.start.assert_called_with("bin", ["foo", "bar"])
def test_placeholder(self): def test_placeholder(self):
"""Test starting editor with placeholder argument.""" """Test starting editor with placeholder argument."""
editorutils.config = ConfigStub(editor=["bin", "foo", "{}", "bar"]) editorutils.config = ConfigStub(
{'general': {'editor': ['bin', 'foo', '{}', 'bar']}})
self.editor.edit("") self.editor.edit("")
filename = self.editor.filename filename = self.editor.filename
self.editor.proc.start.assert_called_with("bin", self.editor.proc.start.assert_called_with("bin",
@ -114,7 +72,8 @@ class ArgTests(TestCase):
def test_in_arg_placeholder(self): def test_in_arg_placeholder(self):
"""Test starting editor with placeholder argument inside argument.""" """Test starting editor with placeholder argument inside argument."""
editorutils.config = ConfigStub(editor=["bin", "foo{}bar"]) editorutils.config = ConfigStub(
{'general': {'editor': ['bin', 'foo{}bar']}})
self.editor.edit("") self.editor.edit("")
self.editor.proc.start.assert_called_with("bin", ["foo{}bar"]) self.editor.proc.start.assert_called_with("bin", ["foo{}bar"])
@ -122,7 +81,7 @@ class ArgTests(TestCase):
self.editor._cleanup() # pylint: disable=protected-access self.editor._cleanup() # pylint: disable=protected-access
class FileHandlingTests(TestCase): class FileHandlingTests(unittest.TestCase):
"""Test creation/deletion of tempfile. """Test creation/deletion of tempfile.
@ -132,7 +91,7 @@ class FileHandlingTests(TestCase):
def setUp(self): def setUp(self):
self.editor = editorutils.ExternalEditor() self.editor = editorutils.ExternalEditor()
editorutils.config = ConfigStub(editor=[""]) editorutils.config = ConfigStub({'general': {'editor': ['']}})
def test_file_handling_closed_ok(self): def test_file_handling_closed_ok(self):
"""Test file handling when closing with an exitstatus == 0.""" """Test file handling when closing with an exitstatus == 0."""
@ -160,7 +119,7 @@ class FileHandlingTests(TestCase):
self.assertFalse(os.path.exists(filename)) self.assertFalse(os.path.exists(filename))
class TextModifyTests(TestCase): class TextModifyTests(unittest.TestCase):
"""Tests to test if the text gets saved/loaded correctly. """Tests to test if the text gets saved/loaded correctly.
@ -171,7 +130,7 @@ class TextModifyTests(TestCase):
def setUp(self): def setUp(self):
self.editor = editorutils.ExternalEditor() self.editor = editorutils.ExternalEditor()
self.editor.editing_finished = Mock() self.editor.editing_finished = Mock()
editorutils.config = ConfigStub(editor=[""]) editorutils.config = ConfigStub({'general': {'editor': ['']}})
def _write(self, text): def _write(self, text):
"""Write a text to the file opened in the fake editor. """Write a text to the file opened in the fake editor.
@ -227,7 +186,7 @@ class TextModifyTests(TestCase):
self.editor.editing_finished.emit.assert_called_with("\u2601") self.editor.editing_finished.emit.assert_called_with("\u2601")
class ErrorMessageTests(TestCase): class ErrorMessageTests(unittest.TestCase):
"""Test if statusbar error messages get emitted correctly. """Test if statusbar error messages get emitted correctly.
@ -235,9 +194,11 @@ class ErrorMessageTests(TestCase):
editor: The ExternalEditor instance to test. editor: The ExternalEditor instance to test.
""" """
# pylint: disable=maybe-no-member
def setUp(self): def setUp(self):
self.editor = editorutils.ExternalEditor() self.editor = editorutils.ExternalEditor()
editorutils.config = ConfigStub(editor=[""]) editorutils.config = ConfigStub({'general': {'editor': ['']}})
def test_proc_error(self): def test_proc_error(self):
"""Test on_proc_error.""" """Test on_proc_error."""

View File

@ -17,20 +17,17 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=protected-access,invalid-name
"""Tests for qutebrowser.utils.log.""" """Tests for qutebrowser.utils.log."""
import logging import logging
import unittest import unittest
import argparse import argparse
import sys import sys
from unittest import TestCase
import qutebrowser.utils.log as log import qutebrowser.utils.log as log
class BaseTest(TestCase): class BaseTest(unittest.TestCase):
"""Base class for logging tests. """Base class for logging tests.
@ -39,6 +36,7 @@ class BaseTest(TestCase):
def setUp(self): def setUp(self):
"""Save the old logging configuration.""" """Save the old logging configuration."""
# pylint: disable=protected-access
logger_dict = logging.getLogger().manager.loggerDict logger_dict = logging.getLogger().manager.loggerDict
logging._acquireLock() logging._acquireLock()
try: try:
@ -57,6 +55,7 @@ class BaseTest(TestCase):
def tearDown(self): def tearDown(self):
"""Restore the original logging configuration.""" """Restore the original logging configuration."""
# pylint: disable=protected-access
while self.root_logger.handlers: while self.root_logger.handlers:
h = self.root_logger.handlers[0] h = self.root_logger.handlers[0]
self.root_logger.removeHandler(h) self.root_logger.removeHandler(h)
@ -67,9 +66,9 @@ class BaseTest(TestCase):
logging._handlers.clear() logging._handlers.clear()
logging._handlers.update(self.saved_handlers) logging._handlers.update(self.saved_handlers)
logging._handlerList[:] = self.saved_handler_list logging._handlerList[:] = self.saved_handler_list
loggerDict = logging.getLogger().manager.loggerDict logger_dict = logging.getLogger().manager.loggerDict
loggerDict.clear() logger_dict.clear()
loggerDict.update(self.saved_loggers) logger_dict.update(self.saved_loggers)
logger_states = self.logger_states logger_states = self.logger_states
for name in self.logger_states: for name in self.logger_states:
if logger_states[name] is not None: if logger_states[name] is not None:
@ -78,7 +77,7 @@ class BaseTest(TestCase):
logging._releaseLock() logging._releaseLock()
class LogFilterTests(TestCase): class LogFilterTests(unittest.TestCase):
"""Tests for LogFilter. """Tests for LogFilter.

View File

@ -17,8 +17,6 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring,blacklisted-name,protected-access
"""Tests for qutebrowser.utils.misc.""" """Tests for qutebrowser.utils.misc."""
import os import os
@ -28,7 +26,6 @@ import unittest
import os.path import os.path
import subprocess import subprocess
from tempfile import mkdtemp from tempfile import mkdtemp
from unittest import TestCase
from PyQt5.QtCore import QStandardPaths, QCoreApplication from PyQt5.QtCore import QStandardPaths, QCoreApplication
from PyQt5.QtGui import QColor from PyQt5.QtGui import QColor
@ -37,7 +34,7 @@ import qutebrowser.utils.misc as utils
from qutebrowser.test.helpers import environ_set_temp from qutebrowser.test.helpers import environ_set_temp
class ElidingTests(TestCase): class ElidingTests(unittest.TestCase):
"""Test elide.""" """Test elide."""
@ -61,7 +58,7 @@ class ElidingTests(TestCase):
self.assertEqual(utils.elide('foobar', 3), 'fo' + self.ELLIPSIS) self.assertEqual(utils.elide('foobar', 3), 'fo' + self.ELLIPSIS)
class ReadFileTests(TestCase): class ReadFileTests(unittest.TestCase):
"""Test read_file.""" """Test read_file."""
@ -71,7 +68,7 @@ class ReadFileTests(TestCase):
self.assertEqual(content.splitlines()[0], "Hello World!") self.assertEqual(content.splitlines()[0], "Hello World!")
class DottedGetattrTests(TestCase): class DottedGetattrTests(unittest.TestCase):
"""Test dotted_getattr. """Test dotted_getattr.
@ -106,7 +103,7 @@ class DottedGetattrTests(TestCase):
_ = utils.dotted_getattr(self, 'test.foo.baz') _ = utils.dotted_getattr(self, 'test.foo.baz')
class SafeShlexSplitTests(TestCase): class SafeShlexSplitTests(unittest.TestCase):
"""Test safe_shlex_split.""" """Test safe_shlex_split."""
@ -141,7 +138,7 @@ class SafeShlexSplitTests(TestCase):
self.assertEqual(items, ['one', 'two\\']) self.assertEqual(items, ['one', 'two\\'])
class ShellEscapeTests(TestCase): class ShellEscapeTests(unittest.TestCase):
"""Tests for shell_escape. """Tests for shell_escape.
@ -204,7 +201,7 @@ class ShellEscapeTests(TestCase):
sys.platform = self.platform sys.platform = self.platform
class GetStandardDirLinuxTests(TestCase): class GetStandardDirLinuxTests(unittest.TestCase):
"""Tests for get_standard_dir under Linux. """Tests for get_standard_dir under Linux.
@ -278,7 +275,7 @@ class GetStandardDirLinuxTests(TestCase):
shutil.rmtree(self.temp_dir) shutil.rmtree(self.temp_dir)
class GetStandardDirWindowsTests(TestCase): class GetStandardDirWindowsTests(unittest.TestCase):
"""Tests for get_standard_dir under Windows. """Tests for get_standard_dir under Windows.
@ -328,7 +325,7 @@ class GetStandardDirWindowsTests(TestCase):
self.app.quit() self.app.quit()
class InterpolateColorTests(TestCase): class InterpolateColorTests(unittest.TestCase):
"""Tests for interpolate_color. """Tests for interpolate_color.
@ -416,7 +413,7 @@ class InterpolateColorTests(TestCase):
self.assertEqual(color, expected) self.assertEqual(color, expected)
class FormatSecondsTests(TestCase): class FormatSecondsTests(unittest.TestCase):
"""Tests for format_seconds. """Tests for format_seconds.
@ -444,7 +441,7 @@ class FormatSecondsTests(TestCase):
self.assertEqual(utils.format_seconds(seconds), out, seconds) self.assertEqual(utils.format_seconds(seconds), out, seconds)
class FormatSizeTests(TestCase): class FormatSizeTests(unittest.TestCase):
"""Tests for format_size. """Tests for format_size.

View File

@ -21,76 +21,19 @@
import os import os
import unittest import unittest
from unittest import TestCase
from unittest.mock import Mock from unittest.mock import Mock
import qutebrowser.utils.misc as utils import qutebrowser.utils.misc as utils
from qutebrowser.test.stubs import FakeNetworkReply
DEFAULT_NAME = 'qutebrowser-download' DEFAULT_NAME = 'qutebrowser-download'
class FakeUrl:
"""QUrl stub which provides .path()."""
def __init__(self, path=None):
self.path = Mock(return_value=path)
class FakeNetworkReply:
"""QNetworkReply stub which provides a Content-Disposition header."""
def __init__(self, content_disposition=None, url=None):
if url is None:
url = FakeUrl()
self._content_disposition = content_disposition
self.url = Mock(return_value=url)
def hasRawHeader(self, name):
"""Check if the reply has a certain header.
Args:
name: The name of the header.
Return:
True if the header is present, False if not.
Raise:
ValueError: If a header other than Content-Disposition is
requested.
"""
if name == 'Content-Disposition':
return self._content_disposition is not None
else:
raise ValueError("Invalid header {}".format(name))
def rawHeader(self, name):
"""Get the raw header data of a header.
Args:
name: The name of the header.
Return:
The header data, as ISO-8859-1 encoded bytes() object.
Raise:
ValueError: If a header other than Content-Disposition is
requested.
"""
if name != 'Content-Disposition':
raise ValueError("Invalid header {}".format(name))
cd = self._content_disposition
if cd is None:
raise ValueError("Content-Disposition is None!")
return cd.encode('iso-8859-1')
# These test cases are based on http://greenbytes.de/tech/tc2231/ # These test cases are based on http://greenbytes.de/tech/tc2231/
class AttachmentTestCase(TestCase): class AttachmentTestCase(unittest.TestCase):
"""Helper class with some convienence methods to check filenames.""" """Helper class with some convienence methods to check filenames."""
@ -117,7 +60,7 @@ class AttachmentTestCase(TestCase):
self.assertFalse(cd_inline) self.assertFalse(cd_inline)
class InlineTests(TestCase): class InlineTests(unittest.TestCase):
"""Various tests relating to the "inline" disposition type. """Various tests relating to the "inline" disposition type.

View File

@ -17,19 +17,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring,blacklisted-name,protected-access
"""Tests for qutebrowser.utils.qt.""" """Tests for qutebrowser.utils.qt."""
import sys import sys
import argparse import argparse
import unittest import unittest
from unittest import TestCase
import qutebrowser.utils.qt as qt import qutebrowser.utils.qt as qt
class CheckOverflowTests(TestCase): class CheckOverflowTests(unittest.TestCase):
"""Test check_overflow. """Test check_overflow.
@ -83,7 +80,7 @@ class CheckOverflowTests(TestCase):
"{}: {}".format(ctype, val)) "{}: {}".format(ctype, val))
class GetQtArgsTests(TestCase): class GetQtArgsTests(unittest.TestCase):
"""Tests for get_qt_args.""" """Tests for get_qt_args."""

View File

@ -17,31 +17,19 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring
"""Tests for qutebrowser.utils.readline.""" """Tests for qutebrowser.utils.readline."""
import inspect import inspect
import unittest import unittest
from unittest import TestCase
from unittest.mock import Mock from unittest.mock import Mock
from PyQt5.QtWidgets import QLineEdit from PyQt5.QtWidgets import QLineEdit
import qutebrowser.utils.readline as readline import qutebrowser.utils.readline as readline
from qutebrowser.test.stubs import FakeQApplication
class FakeQApplication: class NoneWidgetTests(unittest.TestCase):
"""Stub to insert as QApplication module."""
def __init__(self, focus):
# pylint: disable=invalid-name
self.focusWidget = Mock(return_value=focus)
self.instance = Mock(return_value=self)
class NoneWidgetTests(TestCase):
"""Tests when the focused widget is None.""" """Tests when the focused widget is None."""
@ -56,7 +44,7 @@ class NoneWidgetTests(TestCase):
method() method()
class ReadlineBridgeTest(TestCase): class ReadlineBridgeTest(unittest.TestCase):
"""Tests for readline bridge.""" """Tests for readline bridge."""
@ -71,34 +59,42 @@ class ReadlineBridgeTest(TestCase):
self.qle.configure_mock(**{'selectedText.return_value': text}) self.qle.configure_mock(**{'selectedText.return_value': text})
def test_rl_backward_char(self): def test_rl_backward_char(self):
"""Test rl_backward_char."""
self.bridge.rl_backward_char() self.bridge.rl_backward_char()
self.qle.cursorBackward.assert_called_with(False) self.qle.cursorBackward.assert_called_with(False)
def test_rl_forward_char(self): def test_rl_forward_char(self):
"""Test rl_forward_char."""
self.bridge.rl_forward_char() self.bridge.rl_forward_char()
self.qle.cursorForward.assert_called_with(False) self.qle.cursorForward.assert_called_with(False)
def test_rl_backward_word(self): def test_rl_backward_word(self):
"""Test rl_backward_word."""
self.bridge.rl_backward_word() self.bridge.rl_backward_word()
self.qle.cursorWordBackward.assert_called_with(False) self.qle.cursorWordBackward.assert_called_with(False)
def test_rl_forward_word(self): def test_rl_forward_word(self):
"""Test rl_forward_word."""
self.bridge.rl_forward_word() self.bridge.rl_forward_word()
self.qle.cursorWordForward.assert_called_with(False) self.qle.cursorWordForward.assert_called_with(False)
def test_rl_beginning_of_line(self): def test_rl_beginning_of_line(self):
"""Test rl_beginning_of_line."""
self.bridge.rl_beginning_of_line() self.bridge.rl_beginning_of_line()
self.qle.home.assert_called_with(False) self.qle.home.assert_called_with(False)
def test_rl_end_of_line(self): def test_rl_end_of_line(self):
"""Test rl_end_of_line."""
self.bridge.rl_end_of_line() self.bridge.rl_end_of_line()
self.qle.end.assert_called_with(False) self.qle.end.assert_called_with(False)
def test_rl_delete_char(self): def test_rl_delete_char(self):
"""Test rl_delete_char."""
self.bridge.rl_delete_char() self.bridge.rl_delete_char()
self.qle.del_.assert_called_with() self.qle.del_.assert_called_with()
def test_rl_backward_delete_char(self): def test_rl_backward_delete_char(self):
"""Test rl_backward_delete_char."""
self.bridge.rl_backward_delete_char() self.bridge.rl_backward_delete_char()
self.qle.backspace.assert_called_with() self.qle.backspace.assert_called_with()

View File

@ -17,54 +17,26 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring,protected-access
"""Tests for qutebrowser.utils.url.""" """Tests for qutebrowser.utils.url."""
import unittest import unittest
from unittest import TestCase
from PyQt5.QtCore import QUrl from PyQt5.QtCore import QUrl
import qutebrowser.utils.url as urlutils import qutebrowser.utils.url as urlutils
from qutebrowser.test.stubs import ConfigStub
class ConfigStub: CONFIG = {
"""Stub which is used to mock out the config.
Attributes:
_DATA: The config data to use
"""
_DATA = {
'general': {'auto-search': True}, 'general': {'auto-search': True},
'searchengines': { 'searchengines': {
'test': 'http://www.qutebrowser.org/?q={}', 'test': 'http://www.qutebrowser.org/?q={}',
'DEFAULT': 'http://www.example.com/?q={}', 'DEFAULT': 'http://www.example.com/?q={}',
}, },
} }
class NoOptionError(Exception):
"""NoOptionError exception which does nothing."""
pass
def get(self, section, option):
"""Get a value from section/option.
Raise:
NoOptionError if the option was not found.
"""
sect = self._DATA[section]
try:
return sect[option]
except KeyError:
raise self.NoOptionError
class SpecialURLTests(TestCase): class SpecialURLTests(unittest.TestCase):
"""Test is_special_url. """Test is_special_url.
@ -97,7 +69,7 @@ class SpecialURLTests(TestCase):
self.assertFalse(urlutils.is_special_url(u)) self.assertFalse(urlutils.is_special_url(u))
class SearchUrlTests(TestCase): class SearchUrlTests(unittest.TestCase):
"""Test _get_search_url. """Test _get_search_url.
@ -105,9 +77,11 @@ class SearchUrlTests(TestCase):
config: The urlutils.config instance. config: The urlutils.config instance.
""" """
# pylint: disable=protected-access
def setUp(self): def setUp(self):
self.config = urlutils.config self.config = urlutils.config
urlutils.config = ConfigStub() urlutils.config = ConfigStub(CONFIG)
def test_default_engine(self): def test_default_engine(self):
"""Test default search engine.""" """Test default search engine."""
@ -136,7 +110,7 @@ class SearchUrlTests(TestCase):
urlutils.config = self.config urlutils.config = self.config
class IsUrlNaiveTests(TestCase): class IsUrlNaiveTests(unittest.TestCase):
"""Tests for _is_url_naive. """Tests for _is_url_naive.
@ -158,6 +132,8 @@ class IsUrlNaiveTests(TestCase):
'foo', 'foo',
) )
# pylint: disable=protected-access
def test_urls(self): def test_urls(self):
"""Test things which are URLs.""" """Test things which are URLs."""
for url in self.URLS: for url in self.URLS:

View File

@ -17,104 +17,18 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring,invalid-name
"""Tests for the webelement utils.""" """Tests for the webelement utils."""
import unittest import unittest
from unittest import TestCase
from unittest.mock import Mock
from PyQt5.QtCore import QRect, QPoint from PyQt5.QtCore import QRect, QPoint
from PyQt5.QtWebKit import QWebElement
import qutebrowser.utils.webelem as webelem import qutebrowser.utils.webelem as webelem
from qutebrowser.test.stubs import (FakeWebElement, FakeWebFrame,
FakeChildrenFrame)
class FakeWebElement: class IsVisibleInvalidTests(unittest.TestCase):
"""A stub for QWebElement."""
def __init__(self, geometry=None, frame=None, null=False, visibility='',
display='', attributes=None):
"""Constructor.
Args:
geometry: The geometry of the QWebElement as QRect.
frame: The QWebFrame the element is in.
null: Whether the element is null or not.
visibility: The CSS visibility style property calue.
display: The CSS display style property calue.
attributes: Boolean HTML attributes to be added.
Raise:
ValueError if element is not null and geometry/frame are not given.
"""
self.geometry = Mock(return_value=geometry)
self.webFrame = Mock(return_value=frame)
self.isNull = Mock(return_value=null)
self._visibility = visibility
self._display = display
self._attributes = attributes
def styleProperty(self, name, strategy):
"""Return the CSS style property named name.
Only display/visibility and ComputedStyle are simulated.
Raise:
ValueError if strategy is not ComputedStyle or name is not
visibility/display.
"""
if strategy != QWebElement.ComputedStyle:
raise ValueError("styleProperty called with strategy != "
"ComputedStyle ({})!".format(strategy))
if name == 'visibility':
return self._visibility
elif name == 'display':
return self._display
else:
raise ValueError("styleProperty called with unknown name "
"'{}'".format(name))
def hasAttribute(self, name):
"""Check if the element has an attribute named name."""
if self._attributes is None:
return False
else:
return name in self._attributes
class FakeWebFrame:
"""A stub for QWebFrame."""
def __init__(self, geometry, scroll=None, parent=None):
"""Constructor.
Args:
geometry: The geometry of the frame as QRect.
scroll: The scroll position as QPoint.
parent: The parent frame.
"""
if scroll is None:
scroll = QPoint(0, 0)
self.geometry = Mock(return_value=geometry)
self.scrollPosition = Mock(return_value=scroll)
self.parentFrame = Mock(return_value=parent)
class FakeChildrenFrame:
"""A stub for QWebFrame to test get_child_frames."""
def __init__(self, children=None):
if children is None:
children = []
self.childFrames = Mock(return_value=children)
class IsVisibleInvalidTests(TestCase):
"""Tests for is_visible with invalid elements. """Tests for is_visible with invalid elements.
@ -156,7 +70,7 @@ class IsVisibleInvalidTests(TestCase):
self.assertTrue(webelem.is_visible(elem, self.frame)) self.assertTrue(webelem.is_visible(elem, self.frame))
class IsVisibleScrollTests(TestCase): class IsVisibleScrollTests(unittest.TestCase):
"""Tests for is_visible when the frame is scrolled. """Tests for is_visible when the frame is scrolled.
@ -178,7 +92,7 @@ class IsVisibleScrollTests(TestCase):
self.assertTrue(webelem.is_visible(elem, self.frame)) self.assertTrue(webelem.is_visible(elem, self.frame))
class IsVisibleCssTests(TestCase): class IsVisibleCssTests(unittest.TestCase):
"""Tests for is_visible with CSS attributes. """Tests for is_visible with CSS attributes.
@ -213,7 +127,7 @@ class IsVisibleCssTests(TestCase):
self.assertFalse(webelem.is_visible(elem, self.frame)) self.assertFalse(webelem.is_visible(elem, self.frame))
class IsVisibleIframeTests(TestCase): class IsVisibleIframeTests(unittest.TestCase):
"""Tests for is_visible with a child frame. """Tests for is_visible with a child frame.
@ -290,7 +204,7 @@ class IsVisibleIframeTests(TestCase):
self.assertTrue(webelem.is_visible(self.elem4, self.frame)) self.assertTrue(webelem.is_visible(self.elem4, self.frame))
class IsWritableTests(TestCase): class IsWritableTests(unittest.TestCase):
"""Check is_writable.""" """Check is_writable."""
@ -310,7 +224,7 @@ class IsWritableTests(TestCase):
self.assertFalse(webelem.is_writable(elem)) self.assertFalse(webelem.is_writable(elem))
class JavascriptEscapeTests(TestCase): class JavascriptEscapeTests(unittest.TestCase):
"""Check javascript_escape. """Check javascript_escape.
@ -326,11 +240,12 @@ class JavascriptEscapeTests(TestCase):
) )
def test_fake_escape(self): def test_fake_escape(self):
"""Test javascript escaping."""
for before, after in self.STRINGS: for before, after in self.STRINGS:
self.assertEqual(webelem.javascript_escape(before), after) self.assertEqual(webelem.javascript_escape(before), after)
class GetChildFramesTests(TestCase): class GetChildFramesTests(unittest.TestCase):
"""Check get_child_frames.""" """Check get_child_frames."""

View File

@ -17,17 +17,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=missing-docstring
"""Tests for the Enum class.""" """Tests for the Enum class."""
import unittest import unittest
from unittest import TestCase
from qutebrowser.utils.usertypes import enum from qutebrowser.utils.usertypes import enum
class EnumTests(TestCase): class EnumTests(unittest.TestCase):
"""Test simple enums. """Test simple enums.

View File

@ -17,17 +17,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# pylint: disable=protected-access,missing-docstring
"""Tests for the NeighborList class.""" """Tests for the NeighborList class."""
import unittest import unittest
from unittest import TestCase
from qutebrowser.utils.usertypes import NeighborList from qutebrowser.utils.usertypes import NeighborList
class InitTests(TestCase): class InitTests(unittest.TestCase):
"""Just try to init some neighborlists. """Just try to init some neighborlists.
@ -62,7 +59,7 @@ class InitTests(TestCase):
self.assertNotIn(4, nl) self.assertNotIn(4, nl)
class DefaultTests(TestCase): class DefaultTests(unittest.TestCase):
"""Test the default argument. """Test the default argument.
@ -86,7 +83,7 @@ class DefaultTests(TestCase):
self.assertIsNone(nl.idx) self.assertIsNone(nl.idx)
class EmptyTests(TestCase): class EmptyTests(unittest.TestCase):
"""Tests with no items. """Tests with no items.
@ -118,7 +115,7 @@ class EmptyTests(TestCase):
self.nl.getitem(1) self.nl.getitem(1)
class ItemTests(TestCase): class ItemTests(unittest.TestCase):
"""Tests with items. """Tests with items.
@ -175,7 +172,7 @@ class ItemTests(TestCase):
self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.idx, 0)
class OneTests(TestCase): class OneTests(unittest.TestCase):
"""Tests with a list with only one item. """Tests with a list with only one item.
@ -183,6 +180,8 @@ class OneTests(TestCase):
nl: The NeighborList we're testing. nl: The NeighborList we're testing.
""" """
# pylint: disable=protected-access
def setUp(self): def setUp(self):
self.nl = NeighborList([1], default=1) self.nl = NeighborList([1], default=1)
@ -237,7 +236,7 @@ class OneTests(TestCase):
self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.idx, 0)
class BlockTests(TestCase): class BlockTests(unittest.TestCase):
"""Tests with mode=block. """Tests with mode=block.
@ -264,7 +263,7 @@ class BlockTests(TestCase):
self.assertEqual(self.nl.idx, 4) self.assertEqual(self.nl.idx, 4)
class WrapTests(TestCase): class WrapTests(unittest.TestCase):
"""Tests with mode=wrap. """Tests with mode=wrap.
@ -291,7 +290,7 @@ class WrapTests(TestCase):
self.assertEqual(self.nl.idx, 0) self.assertEqual(self.nl.idx, 0)
class RaiseTests(TestCase): class RaiseTests(unittest.TestCase):
"""Tests with mode=exception. """Tests with mode=exception.
@ -320,7 +319,7 @@ class RaiseTests(TestCase):
self.assertEqual(self.nl.idx, 4) self.assertEqual(self.nl.idx, 4)
class SnapInTests(TestCase): class SnapInTests(unittest.TestCase):
"""Tests for the fuzzyval/_snap_in features. """Tests for the fuzzyval/_snap_in features.