100% test coverage for misc.guiprocess.

This commit is contained in:
Florian Bruhin 2015-08-19 07:57:02 +02:00
parent 8fe3a1e9ce
commit aca082ce83
2 changed files with 60 additions and 11 deletions

View File

@ -49,6 +49,7 @@ PERFECT_FILES = [
'qutebrowser/misc/split.py', 'qutebrowser/misc/split.py',
'qutebrowser/misc/msgbox.py', 'qutebrowser/misc/msgbox.py',
'qutebrowser/misc/checkpyver.py', 'qutebrowser/misc/checkpyver.py',
'qutebrowser/misc/guiprocess.py',
'qutebrowser/mainwindow/statusbar/keystring.py', 'qutebrowser/mainwindow/statusbar/keystring.py',
'qutebrowser/mainwindow/statusbar/percentage.py', 'qutebrowser/mainwindow/statusbar/percentage.py',

View File

@ -21,11 +21,12 @@
import os import os
import sys import sys
import json
import textwrap import textwrap
import logging import logging
import pytest import pytest
from PyQt5.QtCore import QProcess from PyQt5.QtCore import QProcess, QIODevice
from helpers import messagemock # pylint: disable=import-error from helpers import messagemock # pylint: disable=import-error
from qutebrowser.misc import guiprocess from qutebrowser.misc import guiprocess
@ -51,7 +52,7 @@ def proc(qtbot):
if os.name == 'nt': if os.name == 'nt':
# WORKAROUND for https://github.com/pytest-dev/pytest-qt/issues/67 # WORKAROUND for https://github.com/pytest-dev/pytest-qt/issues/67
pytest.skip("Test is flaky on Windows...") pytest.skip("Test is flaky on Windows...")
p = guiprocess.GUIProcess(0, 'test') p = guiprocess.GUIProcess(0, 'testprocess')
yield p yield p
if p._proc.state() == QProcess.Running: if p._proc.state() == QProcess.Running:
with qtbot.waitSignal(p.finished, timeout=10000) as blocker: with qtbot.waitSignal(p.finished, timeout=10000) as blocker:
@ -63,7 +64,7 @@ def proc(qtbot):
@pytest.fixture() @pytest.fixture()
def fake_proc(monkeypatch, stubs): def fake_proc(monkeypatch, stubs):
"""A fixture providing a GUIProcess with a mocked QProcess.""" """A fixture providing a GUIProcess with a mocked QProcess."""
p = guiprocess.GUIProcess(0, 'test') p = guiprocess.GUIProcess(0, 'testprocess')
monkeypatch.setattr(p, '_proc', stubs.fake_qprocess()) monkeypatch.setattr(p, '_proc', stubs.fake_qprocess())
return p return p
@ -94,21 +95,67 @@ def test_start_verbose(proc, qtbot, guiprocess_message_mock):
assert msgs[0].level == messagemock.Level.info assert msgs[0].level == messagemock.Level.info
assert msgs[1].level == messagemock.Level.info assert msgs[1].level == messagemock.Level.info
assert msgs[0].text.startswith("Executing:") assert msgs[0].text.startswith("Executing:")
assert msgs[1].text == "Test exited successfully." assert msgs[1].text == "Testprocess exited successfully."
assert bytes(proc._proc.readAll()).rstrip() == b'test' assert bytes(proc._proc.readAll()).rstrip() == b'test'
@pytest.mark.parametrize('argv', [ # WORKAROUND for https://github.com/pytest-dev/pytest-qt/issues/67
pytest.mark.not_frozen(_py_proc('import sys; sys.exit(0)')), @pytest.mark.skipif(os.name == 'nt', reason="Test is flaky on Windows...")
('does_not', 'exist'), @pytest.mark.not_frozen
]) def test_start_env(monkeypatch, qtbot):
def test_start_detached(fake_proc, argv): monkeypatch.setenv('QUTEBROWSER_TEST_1', '1')
env = {'QUTEBROWSER_TEST_2': '2'}
proc = guiprocess.GUIProcess(0, 'testprocess', additional_env=env)
argv = _py_proc("""
import os
import json
env = dict(os.environ)
print(json.dumps(env))
sys.exit(0)
""")
with qtbot.waitSignals([proc.started, proc.finished], raising=True,
timeout=10000):
proc.start(*argv)
data = bytes(proc._proc.readAll()).decode('utf-8')
ret_env = json.loads(data)
assert 'QUTEBROWSER_TEST_1' in ret_env
assert 'QUTEBROWSER_TEST_2' in ret_env
@pytest.mark.not_frozen
@pytest.mark.qt_log_ignore('QIODevice::read.*: WriteOnly device')
def test_start_mode(proc, qtbot):
"""Test simply starting a process with mode parameter."""
with qtbot.waitSignals([proc.started, proc.finished], raising=True,
timeout=10000):
argv = _py_proc("import sys; print('test'); sys.exit(0)")
proc.start(*argv, mode=QIODevice.NotOpen)
assert not proc._proc.readAll()
def test_start_detached(fake_proc):
"""Test starting a detached process.""" """Test starting a detached process."""
argv = ['foo', 'bar']
fake_proc._proc.startDetached.return_value = (True, 0) fake_proc._proc.startDetached.return_value = (True, 0)
fake_proc.start_detached(*argv) fake_proc.start_detached(*argv)
fake_proc._proc.startDetached.assert_called_with(*list(argv) + [None]) fake_proc._proc.startDetached.assert_called_with(*list(argv) + [None])
def test_start_detached_error(fake_proc, guiprocess_message_mock):
"""Test starting a detached process with ok=False."""
argv = ['foo', 'bar']
fake_proc._proc.startDetached.return_value = (False, 0)
fake_proc._proc.error.return_value = "Error message"
fake_proc.start_detached(*argv)
msg = guiprocess_message_mock.getmsg()
assert msg.level == messagemock.Level.error
assert msg.text == "Error while spawning testprocess: Error message."
@pytest.mark.not_frozen @pytest.mark.not_frozen
def test_double_start(qtbot, proc): def test_double_start(qtbot, proc):
"""Test starting a GUIProcess twice.""" """Test starting a GUIProcess twice."""
@ -148,7 +195,8 @@ def test_error(qtbot, proc, caplog, guiprocess_message_mock):
msg = guiprocess_message_mock.getmsg() msg = guiprocess_message_mock.getmsg()
assert msg.level == messagemock.Level.error assert msg.level == messagemock.Level.error
expected_msg = "Error while spawning test: The process failed to start." expected_msg = ("Error while spawning testprocess: The process failed to "
"start.")
assert msg.text == expected_msg assert msg.text == expected_msg
@ -159,4 +207,4 @@ def test_exit_unsuccessful(qtbot, proc, guiprocess_message_mock):
msg = guiprocess_message_mock.getmsg() msg = guiprocess_message_mock.getmsg()
assert msg.level == messagemock.Level.error assert msg.level == messagemock.Level.error
assert msg.text == "Test exited with status 1." assert msg.text == "Testprocess exited with status 1."