Various unittest fixes and improvements.
This commit is contained in:
parent
072210c47b
commit
84643b4a39
@ -25,6 +25,7 @@ import logging
|
||||
|
||||
from qutebrowser.browser import http
|
||||
from qutebrowser.test import stubs
|
||||
from qutebrowser.utils import log
|
||||
|
||||
|
||||
DEFAULT_NAME = 'qutebrowser-download'
|
||||
@ -48,7 +49,8 @@ class AttachmentTestCase(unittest.TestCase):
|
||||
def _check_ignored(self, header):
|
||||
"""Check if the passed header is ignored."""
|
||||
reply = stubs.FakeNetworkReply(headers={'Content-Disposition': header})
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
with self.assertLogs(log.rfc6266, logging.ERROR):
|
||||
cd_inline, cd_filename = http.parse_content_disposition(reply)
|
||||
self.assertEqual(cd_filename, DEFAULT_NAME)
|
||||
self.assertTrue(cd_inline)
|
||||
|
||||
@ -93,7 +95,8 @@ class InlineTests(unittest.TestCase):
|
||||
|
||||
This is invalid syntax, thus the header should be ignored.
|
||||
"""
|
||||
self._check_ignored('"inline"')
|
||||
with self.assertLogs(log.rfc6266, logging.ERROR):
|
||||
self._check_ignored('"inline"')
|
||||
|
||||
def test_inlwithasciifilename(self):
|
||||
"""'inline', specifying a filename of foo.html
|
||||
@ -891,15 +894,5 @@ class OurTests(AttachmentTestCase):
|
||||
'foo bar.html')
|
||||
|
||||
|
||||
def setUpModule():
|
||||
"""Disable logging."""
|
||||
logging.disable(logging.ERROR)
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
"""Restore logging."""
|
||||
logging.disable(logging.NOTSET)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -29,7 +29,7 @@ from PyQt5.QtCore import Qt
|
||||
|
||||
from qutebrowser.keyinput import basekeyparser
|
||||
from qutebrowser.test import stubs, helpers
|
||||
from qutebrowser.utils import objreg
|
||||
from qutebrowser.utils import objreg, log
|
||||
|
||||
|
||||
CONFIG = {'input': {'timeout': 100}}
|
||||
@ -47,17 +47,6 @@ fake_keyconfig = mock.Mock(spec=['get_bindings_for'])
|
||||
fake_keyconfig.get_bindings_for.side_effect = lambda s: BINDINGS[s]
|
||||
|
||||
|
||||
def setUpModule():
|
||||
"""Mock out some imports in basekeyparser."""
|
||||
basekeyparser.QObject = mock.Mock()
|
||||
logging.disable(logging.WARNING)
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
"""Restore mocked out stuff."""
|
||||
logging.disable(logging.NOTSET)
|
||||
|
||||
|
||||
class SplitCountTests(unittest.TestCase):
|
||||
|
||||
"""Test the _split_count method.
|
||||
@ -101,13 +90,14 @@ class SplitCountTests(unittest.TestCase):
|
||||
self.assertEqual(self.kp._split_count(), (None, '10foo'))
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
new=stubs.FakeTimer)
|
||||
class ReadConfigTests(unittest.TestCase):
|
||||
|
||||
"""Test reading the config."""
|
||||
|
||||
def setUp(self):
|
||||
objreg.register('key-config', fake_keyconfig)
|
||||
basekeyparser.usertypes.Timer = mock.Mock()
|
||||
|
||||
def tearDown(self):
|
||||
objreg.delete('key-config')
|
||||
@ -132,6 +122,8 @@ class ReadConfigTests(unittest.TestCase):
|
||||
self.assertIn('ctrl+x', kp.special_bindings)
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
new=stubs.FakeTimer)
|
||||
class SpecialKeysTests(unittest.TestCase):
|
||||
|
||||
"""Check execute() with special keys.
|
||||
@ -141,15 +133,13 @@ class SpecialKeysTests(unittest.TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
patcher = mock.patch(
|
||||
'qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
autospec=True)
|
||||
patcher.start()
|
||||
objreg.register('key-config', fake_keyconfig)
|
||||
self.addCleanup(patcher.stop)
|
||||
self.kp = basekeyparser.BaseKeyParser(0)
|
||||
self.kp.execute = mock.Mock()
|
||||
self.kp.read_config('test')
|
||||
with self.assertLogs(log.keyboard, logging.WARNING):
|
||||
# Ignoring keychain 'ccc' in mode 'test' because keychains are not
|
||||
# supported there.
|
||||
self.kp.read_config('test')
|
||||
|
||||
def tearDown(self):
|
||||
objreg.delete('key-config')
|
||||
@ -173,20 +163,19 @@ class SpecialKeysTests(unittest.TestCase):
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
new=stubs.FakeTimer)
|
||||
class KeyChainTests(unittest.TestCase):
|
||||
|
||||
"""Test execute() with keychain support.
|
||||
|
||||
Attributes:
|
||||
kp: The BaseKeyParser to be tested.
|
||||
timermock: The mock to be used as timer.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up mocks and read the test config."""
|
||||
objreg.register('key-config', fake_keyconfig)
|
||||
self.timermock = mock.Mock()
|
||||
basekeyparser.usertypes.Timer = mock.Mock(return_value=self.timermock)
|
||||
self.kp = basekeyparser.BaseKeyParser(0, supports_chains=True,
|
||||
supports_count=False)
|
||||
self.kp.execute = mock.Mock()
|
||||
@ -222,22 +211,20 @@ class KeyChainTests(unittest.TestCase):
|
||||
def test_ambigious_keychain(self):
|
||||
"""Test ambigious keychain."""
|
||||
basekeyparser.config = stubs.ConfigStub(CONFIG)
|
||||
timer = self.kp._ambigious_timer
|
||||
self.assertFalse(timer.isActive())
|
||||
# We start with 'a' where the keychain gives us an ambigious result.
|
||||
# Then we check if the timer has been set up correctly
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_A, text='a'))
|
||||
self.assertFalse(self.kp.execute.called)
|
||||
basekeyparser.usertypes.Timer.assert_called_once_with(
|
||||
self.kp, 'ambigious-match')
|
||||
self.timermock.setSingleShot.assert_called_once_with(True)
|
||||
self.timermock.setInterval.assert_called_once_with(100)
|
||||
self.assertTrue(self.timermock.timeout.connect.called)
|
||||
self.assertFalse(self.timermock.stop.called)
|
||||
self.timermock.start.assert_called_once_with()
|
||||
self.assertTrue(timer.isSingleShot())
|
||||
self.assertEqual(timer.interval(), 100)
|
||||
self.assertTrue(timer.isActive())
|
||||
# Now we type an 'x' and check 'ax' has been executed and the timer
|
||||
# stopped.
|
||||
self.kp.handle(helpers.fake_keyevent(Qt.Key_X, text='x'))
|
||||
self.kp.execute.assert_called_once_with('ax', self.kp.Type.chain, None)
|
||||
self.timermock.stop.assert_called_once_with()
|
||||
self.assertFalse(timer.isActive())
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
def test_invalid_keychain(self):
|
||||
@ -247,13 +234,14 @@ class KeyChainTests(unittest.TestCase):
|
||||
self.assertEqual(self.kp._keystring, '')
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.keyinput.basekeyparser.usertypes.Timer',
|
||||
new=stubs.FakeTimer)
|
||||
class CountTests(unittest.TestCase):
|
||||
|
||||
"""Test execute() with counts."""
|
||||
|
||||
def setUp(self):
|
||||
objreg.register('key-config', fake_keyconfig)
|
||||
basekeyparser.usertypes.Timer = mock.Mock()
|
||||
self.kp = basekeyparser.BaseKeyParser(0, supports_chains=True,
|
||||
supports_count=True)
|
||||
self.kp.execute = mock.Mock()
|
||||
|
@ -24,7 +24,6 @@
|
||||
import os
|
||||
import os.path
|
||||
import unittest
|
||||
import logging
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtCore import QProcess
|
||||
@ -33,18 +32,8 @@ from qutebrowser.misc import editor
|
||||
from qutebrowser.test import stubs
|
||||
|
||||
|
||||
def setUpModule():
|
||||
"""Disable logging and mock out some imports."""
|
||||
logging.disable(logging.INFO)
|
||||
editor.message = mock.Mock()
|
||||
editor.QProcess = stubs.FakeQProcess
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
"""Restore logging."""
|
||||
logging.disable(logging.NOTSET)
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
class ArgTests(unittest.TestCase):
|
||||
|
||||
"""Test argument handling.
|
||||
@ -56,14 +45,14 @@ class ArgTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.editor = editor.ExternalEditor(0)
|
||||
|
||||
def test_simple_start_args(self):
|
||||
def test_simple_start_args(self, _proc_mock):
|
||||
"""Test starting editor without arguments."""
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'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, _proc_mock):
|
||||
"""Test starting editor with static arguments."""
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': ['bin', 'foo', 'bar'],
|
||||
@ -71,17 +60,17 @@ class ArgTests(unittest.TestCase):
|
||||
self.editor.edit("")
|
||||
self.editor._proc.start.assert_called_with("bin", ["foo", "bar"])
|
||||
|
||||
def test_placeholder(self):
|
||||
def test_placeholder(self, _proc_mock):
|
||||
"""Test starting editor with placeholder argument."""
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'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"])
|
||||
self.editor._proc.start.assert_called_with(
|
||||
"bin", ["foo", filename, "bar"])
|
||||
|
||||
def test_in_arg_placeholder(self):
|
||||
def test_in_arg_placeholder(self, _proc_mock):
|
||||
"""Test starting editor with placeholder argument inside argument."""
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': ['bin', 'foo{}bar'],
|
||||
@ -93,6 +82,8 @@ class ArgTests(unittest.TestCase):
|
||||
self.editor._cleanup() # pylint: disable=protected-access
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
class FileHandlingTests(unittest.TestCase):
|
||||
|
||||
"""Test creation/deletion of tempfile.
|
||||
@ -106,7 +97,7 @@ class FileHandlingTests(unittest.TestCase):
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}})
|
||||
|
||||
def test_file_handling_closed_ok(self):
|
||||
def test_file_handling_closed_ok(self, _proc_mock):
|
||||
"""Test file handling when closing with an exitstatus == 0."""
|
||||
self.editor.edit("")
|
||||
filename = self.editor._filename
|
||||
@ -114,7 +105,7 @@ class FileHandlingTests(unittest.TestCase):
|
||||
self.editor.on_proc_closed(0, QProcess.NormalExit)
|
||||
self.assertFalse(os.path.exists(filename))
|
||||
|
||||
def test_file_handling_closed_error(self):
|
||||
def test_file_handling_closed_error(self, _proc_mock):
|
||||
"""Test file handling when closing with an exitstatus != 0."""
|
||||
self.editor.edit("")
|
||||
filename = self.editor._filename
|
||||
@ -122,7 +113,7 @@ class FileHandlingTests(unittest.TestCase):
|
||||
self.editor.on_proc_closed(1, QProcess.NormalExit)
|
||||
self.assertFalse(os.path.exists(filename))
|
||||
|
||||
def test_file_handling_closed_crash(self):
|
||||
def test_file_handling_closed_crash(self, _proc_mock):
|
||||
"""Test file handling when closing with a crash."""
|
||||
self.editor.edit("")
|
||||
filename = self.editor._filename
|
||||
@ -132,6 +123,8 @@ class FileHandlingTests(unittest.TestCase):
|
||||
self.assertFalse(os.path.exists(filename))
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
class TextModifyTests(unittest.TestCase):
|
||||
|
||||
"""Tests to test if the text gets saved/loaded correctly.
|
||||
@ -167,7 +160,7 @@ class TextModifyTests(unittest.TestCase):
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
def test_empty_input(self):
|
||||
def test_empty_input(self, _proc_mock):
|
||||
"""Test if an empty input gets modified correctly."""
|
||||
self.editor.edit("")
|
||||
self.assertEqual(self._read(), "")
|
||||
@ -175,7 +168,7 @@ class TextModifyTests(unittest.TestCase):
|
||||
self.editor.on_proc_closed(0, QProcess.NormalExit)
|
||||
self.editor.editing_finished.emit.assert_called_with("Hello")
|
||||
|
||||
def test_simple_input(self):
|
||||
def test_simple_input(self, _proc_mock):
|
||||
"""Test if an empty input gets modified correctly."""
|
||||
self.editor.edit("Hello")
|
||||
self.assertEqual(self._read(), "Hello")
|
||||
@ -183,7 +176,7 @@ class TextModifyTests(unittest.TestCase):
|
||||
self.editor.on_proc_closed(0, QProcess.NormalExit)
|
||||
self.editor.editing_finished.emit.assert_called_with("World")
|
||||
|
||||
def test_umlaut(self):
|
||||
def test_umlaut(self, _proc_mock):
|
||||
"""Test if umlauts works correctly."""
|
||||
self.editor.edit("Hällö Wörld")
|
||||
self.assertEqual(self._read(), "Hällö Wörld")
|
||||
@ -191,7 +184,7 @@ class TextModifyTests(unittest.TestCase):
|
||||
self.editor.on_proc_closed(0, QProcess.NormalExit)
|
||||
self.editor.editing_finished.emit.assert_called_with("Überprüfung")
|
||||
|
||||
def test_unicode(self):
|
||||
def test_unicode(self, _proc_mock):
|
||||
"""Test if other UTF8 chars work correctly."""
|
||||
self.editor.edit("\u2603") # Unicode snowman
|
||||
self.assertEqual(self._read(), "\u2603")
|
||||
@ -200,6 +193,9 @@ class TextModifyTests(unittest.TestCase):
|
||||
self.editor.editing_finished.emit.assert_called_with("\u2601")
|
||||
|
||||
|
||||
@mock.patch('qutebrowser.misc.editor.QProcess',
|
||||
new_callable=stubs.FakeQProcess)
|
||||
@mock.patch('qutebrowser.misc.editor.message', autospec=True)
|
||||
class ErrorMessageTests(unittest.TestCase):
|
||||
|
||||
"""Test if statusbar error messages get emitted correctly.
|
||||
@ -215,17 +211,17 @@ class ErrorMessageTests(unittest.TestCase):
|
||||
editor.config = stubs.ConfigStub(
|
||||
{'general': {'editor': [''], 'editor-encoding': 'utf-8'}})
|
||||
|
||||
def test_proc_error(self):
|
||||
def test_proc_error(self, msg_mock, _proc_mock):
|
||||
"""Test on_proc_error."""
|
||||
self.editor.edit("")
|
||||
self.editor.on_proc_error(QProcess.Crashed)
|
||||
self.assertTrue(editor.message.error.called)
|
||||
self.assertTrue(msg_mock.error.called)
|
||||
|
||||
def test_proc_return(self):
|
||||
def test_proc_return(self, msg_mock, _proc_mock):
|
||||
"""Test on_proc_finished with a bad exit status."""
|
||||
self.editor.edit("")
|
||||
self.editor.on_proc_closed(1, QProcess.NormalExit)
|
||||
self.assertTrue(editor.message.error.called)
|
||||
self.assertTrue(msg_mock.error.called)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -27,6 +27,7 @@ from PyQt5.QtCore import QPoint, QProcess
|
||||
from PyQt5.QtNetwork import QNetworkRequest
|
||||
|
||||
from qutebrowser.config import configexc
|
||||
from qutebrowser.utils import usertypes
|
||||
|
||||
|
||||
class ConfigStub:
|
||||
@ -178,11 +179,11 @@ class FakeNetworkReply:
|
||||
self.headers[key] = value
|
||||
|
||||
|
||||
class FakeQProcess:
|
||||
class FakeQProcess(mock.Mock):
|
||||
|
||||
"""QProcess stub.
|
||||
|
||||
Gets some enum values from the real QProcess and uses mocks for signals.
|
||||
Gets some enum values from the real QProcess.
|
||||
"""
|
||||
|
||||
NormalExit = QProcess.NormalExit
|
||||
@ -195,11 +196,6 @@ class FakeQProcess:
|
||||
ReadError = QProcess.ReadError
|
||||
UnknownError = QProcess.UnknownError
|
||||
|
||||
def __init__(self, parent=None): # pylint: disable=unused-argument
|
||||
self.finished = mock.Mock()
|
||||
self.error = mock.Mock()
|
||||
self.start = mock.Mock()
|
||||
|
||||
|
||||
class FakeSignal:
|
||||
|
||||
@ -223,3 +219,12 @@ class FakeCommand:
|
||||
|
||||
def __init__(self, desc):
|
||||
self.desc = desc
|
||||
|
||||
|
||||
class FakeTimer(usertypes.Timer):
|
||||
|
||||
"""Stub for a usertypes.Timer."""
|
||||
|
||||
def __init__(self, parent=None, name=None):
|
||||
super().__init__(parent, name)
|
||||
self.blockSignals(True)
|
||||
|
Loading…
Reference in New Issue
Block a user