Reorganize utils.debug tests and add some more.

This commit is contained in:
Florian Bruhin 2015-08-11 07:41:25 +02:00
parent dcaae51b4f
commit 7412e4f723
5 changed files with 173 additions and 238 deletions

View File

@ -1,45 +0,0 @@
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
#
# 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/>.
"""Tests for qutebrowser.utils.debug.log_time."""
import logging
import re
import time
from qutebrowser.utils import debug
def test_log_time(caplog):
"""Test if log_time logs properly."""
logger_name = 'qt-tests'
with caplog.atLevel(logging.DEBUG, logger_name):
with debug.log_time(logging.getLogger(logger_name), action='foobar'):
time.sleep(0.1)
records = caplog.records()
assert len(records) == 1
pattern = re.compile(r'^Foobar took ([\d.]*) seconds\.$')
match = pattern.match(records[0].msg)
assert match
duration = float(match.group(1))
assert 0 < duration < 1

View File

@ -1,64 +0,0 @@
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
#
# 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/>.
"""Tests for qutebrowser.utils.debug.qenum_key."""
import pytest
from PyQt5.QtWidgets import QStyle, QFrame
from qutebrowser.utils import debug
def test_no_metaobj():
"""Test with an enum with no meta-object."""
assert not hasattr(QStyle.PrimitiveElement, 'staticMetaObject')
key = debug.qenum_key(QStyle, QStyle.PE_PanelButtonCommand)
assert key == 'PE_PanelButtonCommand'
def test_metaobj():
"""Test with an enum with meta-object."""
assert hasattr(QFrame, 'staticMetaObject')
key = debug.qenum_key(QFrame, QFrame.Sunken)
assert key == 'Sunken'
def test_add_base():
"""Test with add_base=True."""
key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True)
assert key == 'QFrame.Sunken'
def test_int_noklass():
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
debug.qenum_key(QFrame, 42)
def test_int():
"""Test passing an int with explicit klass given."""
key = debug.qenum_key(QFrame, 0x0030, klass=QFrame.Shadow)
assert key == 'Sunken'
def test_unknown():
"""Test passing an unknown value."""
key = debug.qenum_key(QFrame, 0x1337, klass=QFrame.Shadow)
assert key == '0x1337'

View File

@ -1,77 +0,0 @@
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
#
# 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/>.
"""Tests for qutebrowser.utils.debug.qflags_key.
https://github.com/The-Compiler/qutebrowser/issues/42
"""
import pytest
from PyQt5.QtCore import Qt
from qutebrowser.utils import debug
fixme = pytest.mark.xfail(reason="See issue #42", raises=AssertionError)
@fixme
def test_single():
"""Test with single value."""
flags = debug.qflags_key(Qt, Qt.AlignTop)
assert flags == 'AlignTop'
@fixme
def test_multiple():
"""Test with multiple values."""
flags = debug.qflags_key(Qt, Qt.AlignLeft | Qt.AlignTop)
assert flags == 'AlignLeft|AlignTop'
def test_combined():
"""Test with a combined value."""
flags = debug.qflags_key(Qt, Qt.AlignCenter)
assert flags == 'AlignHCenter|AlignVCenter'
@fixme
def test_add_base():
"""Test with add_base=True."""
flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True)
assert flags == 'Qt.AlignTop'
def test_int_noklass():
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
debug.qflags_key(Qt, 42)
@fixme
def test_int():
"""Test passing an int with explicit klass given."""
flags = debug.qflags_key(Qt, 0x0021, klass=Qt.Alignment)
assert flags == 'AlignLeft|AlignTop'
def test_unknown():
"""Test passing an unknown value."""
flags = debug.qflags_key(Qt, 0x1100, klass=Qt.Alignment)
assert flags == '0x0100|0x1000'

View File

@ -1,52 +0,0 @@
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
#
# 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/>.
"""Test signal debug output functions."""
import pytest
from qutebrowser.utils import debug
@pytest.fixture
def signal(stubs):
"""Fixture to provide a faked pyqtSignal."""
return stubs.FakeSignal()
def test_signal_name(signal):
"""Test signal_name()."""
assert debug.signal_name(signal) == 'fake'
def test_dbg_signal(signal):
"""Test dbg_signal()."""
assert debug.dbg_signal(signal, [23, 42]) == 'fake(23, 42)'
def test_dbg_signal_eliding(signal):
"""Test eliding in dbg_signal()."""
dbg_signal = debug.dbg_signal(signal, ['x' * 201])
assert dbg_signal == "fake('{}\u2026)".format('x' * 198)
def test_dbg_signal_newline(signal):
"""Test dbg_signal() with a newline."""
dbg_signal = debug.dbg_signal(signal, ['foo\nbar'])
assert dbg_signal == r"fake('foo\nbar')"

173
tests/utils/test_debug.py Normal file
View File

@ -0,0 +1,173 @@
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
#
# 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/>.
"""Tests for qutebrowser.utils.debug."""
import logging
import re
import time
import pytest
from PyQt5.QtCore import pyqtSignal, Qt, QEvent, QObject
from PyQt5.QtWidgets import QStyle, QFrame
from qutebrowser.utils import debug
@debug.log_events
class EventObject(QObject):
pass
def test_log_events(qapp, caplog):
obj = EventObject()
qapp.postEvent(obj, QEvent(QEvent.User))
qapp.processEvents()
records = caplog.records()
assert len(records) == 1
assert records[0].msg == 'Event in test_debug.EventObject: User'
class SignalObject(QObject):
signal1 = pyqtSignal()
signal2 = pyqtSignal(str, str)
def __repr__(self):
"""This is not a nice thing to do, but it makes our tests easier."""
return '<repr>'
@debug.log_signals
class DecoratedSignalObject(SignalObject):
pass
@pytest.fixture(params=[(SignalObject, True), (DecoratedSignalObject, False)])
def signal_obj(request):
klass, wrap = request.param
if wrap:
debug.log_signals(klass)
return klass()
def test_log_signals(caplog, signal_obj):
signal_obj.signal1.emit()
signal_obj.signal2.emit('foo', 'bar')
records = caplog.records()
assert len(records) == 2
assert records[0].msg == 'Signal in <repr>: signal1()'
assert records[1].msg == "Signal in <repr>: signal2('foo', 'bar')"
def test_log_time(caplog):
logger_name = 'qt-tests'
with caplog.atLevel(logging.DEBUG, logger_name):
with debug.log_time(logging.getLogger(logger_name), action='foobar'):
time.sleep(0.1)
records = caplog.records()
assert len(records) == 1
pattern = re.compile(r'^Foobar took ([\d.]*) seconds\.$')
match = pattern.match(records[0].msg)
assert match
duration = float(match.group(1))
assert 0 < duration < 1
class TestQEnumKey:
def test_metaobj(self):
"""Make sure the classes we use in the tests have a metaobj or not.
If Qt/PyQt even changes and our tests wouldn't test the full
functionality of qenum_key because of that, this test will tell us.
"""
assert not hasattr(QStyle.PrimitiveElement, 'staticMetaObject')
assert hasattr(QFrame, 'staticMetaObject')
@pytest.mark.parametrize('base, value, klass, expected', [
(QStyle, QStyle.PE_PanelButtonCommand, None, 'PE_PanelButtonCommand'),
(QFrame, QFrame.Sunken, None, 'Sunken'),
(QFrame, 0x0030, QFrame.Shadow, 'Sunken'),
(QFrame, 0x1337, QFrame.Shadow, '0x1337'),
])
def test_qenum_key(self, base, value, klass, expected):
key = debug.qenum_key(base, value, klass=klass)
assert key == expected
def test_add_base(self):
key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True)
assert key == 'QFrame.Sunken'
def test_int_noklass(self):
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
debug.qenum_key(QFrame, 42)
class TestQFlagsKey:
"""Tests for qutebrowser.utils.debug.qflags_key.
https://github.com/The-Compiler/qutebrowser/issues/42
"""
fixme = pytest.mark.xfail(reason="See issue #42", raises=AssertionError)
@pytest.mark.parametrize('base, value, klass, expected', [
fixme((Qt, Qt.AlignTop, None, 'AlignTop')),
fixme((Qt, Qt.AlignLeft | Qt.AlignTop, None, 'AlignLeft|AlignTop')),
(Qt, Qt.AlignCenter, None, 'AlignHCenter|AlignVCenter'),
fixme((Qt, 0x0021, Qt.Alignment, 'AlignLeft|AlignTop')),
(Qt, 0x1100, Qt.Alignment, '0x0100|0x1000'),
])
def test_qflags_key(self, base, value, klass, expected):
flags = debug.qflags_key(base, value, klass=klass)
assert flags == expected
@fixme
def test_add_base(self):
"""Test with add_base=True."""
flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True)
assert flags == 'Qt.AlignTop'
def test_int_noklass(self):
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
debug.qflags_key(Qt, 42)
def test_signal_name(stubs):
assert debug.signal_name(stubs.FakeSignal()) == 'fake'
@pytest.mark.parametrize('args, expected', [
([23, 42], 'fake(23, 42)'),
(['x' * 201], "fake('{}\u2026)".format('x' * 198)),
(['foo\nbar'], r"fake('foo\nbar')"),
])
def test_dbg_signal(stubs, args, expected):
assert debug.dbg_signal(stubs.FakeSignal(), args) == expected