From 6037fd74cd300bb44a69c6bdbfb3cd712552e243 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 8 Apr 2015 20:06:52 -0300 Subject: [PATCH 01/11] Convert test_split to pytest --- tests/misc/test_split.py | 66 ++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/tests/misc/test_split.py b/tests/misc/test_split.py index c2c930b50..340fe6fb1 100644 --- a/tests/misc/test_split.py +++ b/tests/misc/test_split.py @@ -19,7 +19,7 @@ """Tests for qutebrowser.misc.split.""" -import unittest +import pytest from qutebrowser.misc import split @@ -103,38 +103,35 @@ foo\ bar/foo bar/foo\ bar/ áéíóú/áéíóú/áéíóú/ """ +test_data_lines = test_data.strip().splitlines() -class SplitTests(unittest.TestCase): +class TestSplit: """Test split.""" - def test_split(self): + @pytest.mark.parametrize('cmd, out', + [case.split('/')[:-2] for case in test_data_lines]) + def test_split(self, cmd, out): """Test splitting.""" - for case in test_data.strip().splitlines(): - cmd, out = case.split('/')[:-2] - with self.subTest(cmd=cmd): - items = split.split(cmd) - self.assertEqual(items, out.split('|')) + items = split.split(cmd) + assert items == out.split('|') - def test_split_keep_original(self): + @pytest.mark.parametrize('cmd', + [case.split('/')[0] for case in test_data_lines]) + def test_split_keep_original(self, cmd): """Test if splitting with keep=True yields the original string.""" - for case in test_data.strip().splitlines(): - cmd = case.split('/')[0] - with self.subTest(cmd=cmd): - items = split.split(cmd, keep=True) - self.assertEqual(''.join(items), cmd) + items = split.split(cmd, keep=True) + assert ''.join(items) == cmd - def test_split_keep(self): + @pytest.mark.parametrize('cmd, _mid, out', + [case.split('/')[:-1] for case in test_data_lines]) + def test_split_keep(self, cmd, _mid, out): """Test splitting with keep=True.""" - for case in test_data.strip().splitlines(): - cmd, _mid, out = case.split('/')[:-1] - with self.subTest(cmd=cmd): - items = split.split(cmd, keep=True) - self.assertEqual(items, out.split('|')) + items = split.split(cmd, keep=True) + assert items == out.split('|') -class SimpleSplitTests(unittest.TestCase): - +class TestSimpleSplit: """Test simple_split.""" TESTS = { @@ -145,27 +142,22 @@ class SimpleSplitTests(unittest.TestCase): 'foo\nbar': ['foo', '\nbar'], } - def test_str_split(self): + @pytest.mark.parametrize('test', TESTS) + def test_str_split(self, test): """Test if the behavior matches str.split.""" - for test in self.TESTS: - with self.subTest(string=test): - self.assertEqual(split.simple_split(test), - test.rstrip().split()) + assert split.simple_split(test) == test.rstrip().split() def test_str_split_maxsplit_1(self): """Test if the behavior matches str.split with maxsplit=1.""" - string = "foo bar baz" - self.assertEqual(split.simple_split(string, maxsplit=1), - string.rstrip().split(maxsplit=1)) + s = "foo bar baz" + assert split.simple_split(s, maxsplit=1) == s.rstrip().split(maxsplit=1) def test_str_split_maxsplit_0(self): """Test if the behavior matches str.split with maxsplit=0.""" - string = " foo bar baz " - self.assertEqual(split.simple_split(string, maxsplit=0), - string.rstrip().split(maxsplit=0)) + s = " foo bar baz " + assert split.simple_split(s, maxsplit=0) == s.rstrip().split(maxsplit=0) - def test_split_keep(self): + @pytest.mark.parametrize('test, expected', TESTS.items()) + def test_split_keep(self, test, expected): """Test splitting with keep=True.""" - for test, expected in self.TESTS.items(): - with self.subTest(string=test): - self.assertEqual(split.simple_split(test, keep=True), expected) + assert split.simple_split(test, keep=True) == expected From 853280feeb989baa61a1df59c88725f5852716f0 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 8 Apr 2015 20:23:52 -0300 Subject: [PATCH 02/11] Convert test_qtutils to pytest --- tests/utils/test_qtutils.py | 93 +++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/tests/utils/test_qtutils.py b/tests/utils/test_qtutils.py index 582abbf07..b88caada6 100644 --- a/tests/utils/test_qtutils.py +++ b/tests/utils/test_qtutils.py @@ -20,14 +20,14 @@ """Tests for qutebrowser.utils.qtutils.""" import sys -import unittest + +import pytest from qutebrowser import qutebrowser from qutebrowser.utils import qtutils -class CheckOverflowTests(unittest.TestCase): - +class TestCheckOverflow: """Test check_overflow. Class attributes: @@ -58,69 +58,60 @@ class CheckOverflowTests(unittest.TestCase): (float(INT64_MAX + 1), INT64_MAX)], } - def test_good_values(self): + @pytest.mark.parametrize('ctype, val', [(ctype, val) for ctype, vals in + GOOD_VALUES.items() for val in + vals]) + def test_good_values(self, ctype, val): """Test values which are inside bounds.""" - for ctype, vals in self.GOOD_VALUES.items(): - for val in vals: - with self.subTest(ctype=ctype, val=val): - qtutils.check_overflow(val, ctype) + qtutils.check_overflow(val, ctype) - def test_bad_values_fatal(self): + @pytest.mark.parametrize('ctype, val', + [(ctype, val) for ctype, vals in BAD_VALUES.items() + for (val, _) in vals]) + def test_bad_values_fatal(self, ctype, val): """Test values which are outside bounds with fatal=True.""" - for ctype, vals in self.BAD_VALUES.items(): - for (val, _) in vals: - with self.subTest(ctype=ctype, val=val): - with self.assertRaises(OverflowError): - qtutils.check_overflow(val, ctype) + with pytest.raises(OverflowError): + qtutils.check_overflow(val, ctype) - def test_bad_values_nonfatal(self): + @pytest.mark.parametrize('ctype, val, repl', + [(ctype, val, repl) for ctype, vals in + BAD_VALUES.items() for (val, repl) in vals]) + def test_bad_values_nonfatal(self, ctype, val, repl): """Test values which are outside bounds with fatal=False.""" - for ctype, vals in self.BAD_VALUES.items(): - for (val, replacement) in vals: - with self.subTest(ctype=ctype, val=val): - newval = qtutils.check_overflow(val, ctype, fatal=False) - self.assertEqual(newval, replacement) + newval = qtutils.check_overflow(val, ctype, fatal=False) + assert newval == repl -def argparser_exit(status=0, message=None): # pylint: disable=unused-argument - """Function to monkey-patch .exit() of the argparser so it doesn't exit.""" - raise Exception - - -class GetQtArgsTests(unittest.TestCase): - +class TestGetQtArgs: """Tests for get_args.""" - def setUp(self): - self.parser = qutebrowser.get_argparser() - self.parser.exit = argparser_exit + @pytest.fixture + def parser(self, mocker): + parser = qutebrowser.get_argparser() + # monkey-patch .exit() of the argparser so it doesn't exit. + mocker.patch.object(parser, 'exit', side_effect=Exception) + return parser - def test_no_qt_args(self): + def test_no_qt_args(self, parser): """Test commandline with no Qt arguments given.""" - args = self.parser.parse_args(['--debug']) - self.assertEqual(qtutils.get_args(args), [sys.argv[0]]) + args = parser.parse_args(['--debug']) + assert qtutils.get_args(args) == [sys.argv[0]] - def test_qt_flag(self): + def test_qt_flag(self, parser): """Test commandline with a Qt flag.""" - args = self.parser.parse_args(['--debug', '--qt-reverse', '--nocolor']) - self.assertEqual(qtutils.get_args(args), [sys.argv[0], '-reverse']) + args = parser.parse_args(['--debug', '--qt-reverse', '--nocolor']) + assert qtutils.get_args(args) == [sys.argv[0], '-reverse'] - def test_qt_arg(self): + def test_qt_arg(self, parser): """Test commandline with a Qt argument.""" - args = self.parser.parse_args(['--qt-stylesheet', 'foobar']) - self.assertEqual(qtutils.get_args(args), [sys.argv[0], '-stylesheet', - 'foobar']) + args = parser.parse_args(['--qt-stylesheet', 'foobar']) + assert qtutils.get_args(args) == [sys.argv[0], '-stylesheet', 'foobar'] - def test_qt_both(self): + def test_qt_both(self, parser): """Test commandline with a Qt argument and flag.""" - args = self.parser.parse_args(['--qt-stylesheet', 'foobar', - '--qt-reverse']) + args = parser.parse_args(['--qt-stylesheet', 'foobar', '--qt-reverse']) qt_args = qtutils.get_args(args) - self.assertEqual(qt_args[0], sys.argv[0]) - self.assertIn('-reverse', qt_args) - self.assertIn('-stylesheet', qt_args) - self.assertIn('foobar', qt_args) - - -if __name__ == '__main__': - unittest.main() + assert qt_args[0] == sys.argv[0] + assert '-reverse' in qt_args + assert '-stylesheet' in qt_args + assert 'foobar' in qt_args From 74f4642a2c03ed7bcc28fd09e717c719bff360b6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 9 Apr 2015 07:35:33 +0200 Subject: [PATCH 03/11] Fix lint. --- tests/misc/test_split.py | 19 ++++++++++++++----- tests/utils/test_qtutils.py | 11 ++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/tests/misc/test_split.py b/tests/misc/test_split.py index 340fe6fb1..e926368e0 100644 --- a/tests/misc/test_split.py +++ b/tests/misc/test_split.py @@ -107,24 +107,28 @@ test_data_lines = test_data.strip().splitlines() class TestSplit: + """Test split.""" @pytest.mark.parametrize('cmd, out', - [case.split('/')[:-2] for case in test_data_lines]) + [case.split('/')[:-2] + for case in test_data_lines]) def test_split(self, cmd, out): """Test splitting.""" items = split.split(cmd) assert items == out.split('|') @pytest.mark.parametrize('cmd', - [case.split('/')[0] for case in test_data_lines]) + [case.split('/')[0] + for case in test_data_lines]) def test_split_keep_original(self, cmd): """Test if splitting with keep=True yields the original string.""" items = split.split(cmd, keep=True) assert ''.join(items) == cmd @pytest.mark.parametrize('cmd, _mid, out', - [case.split('/')[:-1] for case in test_data_lines]) + [case.split('/')[:-1] + for case in test_data_lines]) def test_split_keep(self, cmd, _mid, out): """Test splitting with keep=True.""" items = split.split(cmd, keep=True) @@ -132,6 +136,7 @@ class TestSplit: class TestSimpleSplit: + """Test simple_split.""" TESTS = { @@ -150,12 +155,16 @@ class TestSimpleSplit: def test_str_split_maxsplit_1(self): """Test if the behavior matches str.split with maxsplit=1.""" s = "foo bar baz" - assert split.simple_split(s, maxsplit=1) == s.rstrip().split(maxsplit=1) + actual = split.simple_split(s, maxsplit=1) + expected = s.rstrip().split(maxsplit=1) + assert actual == expected def test_str_split_maxsplit_0(self): """Test if the behavior matches str.split with maxsplit=0.""" s = " foo bar baz " - assert split.simple_split(s, maxsplit=0) == s.rstrip().split(maxsplit=0) + actual = split.simple_split(s, maxsplit=0) + expected = s.rstrip().split(maxsplit=0) + assert actual == expected @pytest.mark.parametrize('test, expected', TESTS.items()) def test_split_keep(self, test, expected): diff --git a/tests/utils/test_qtutils.py b/tests/utils/test_qtutils.py index b88caada6..e3c5478f8 100644 --- a/tests/utils/test_qtutils.py +++ b/tests/utils/test_qtutils.py @@ -28,6 +28,7 @@ from qutebrowser.utils import qtutils class TestCheckOverflow: + """Test check_overflow. Class attributes: @@ -66,8 +67,8 @@ class TestCheckOverflow: qtutils.check_overflow(val, ctype) @pytest.mark.parametrize('ctype, val', - [(ctype, val) for ctype, vals in BAD_VALUES.items() - for (val, _) in vals]) + [(ctype, val) for ctype, vals in + BAD_VALUES.items() for (val, _) in vals]) def test_bad_values_fatal(self, ctype, val): """Test values which are outside bounds with fatal=True.""" with pytest.raises(OverflowError): @@ -83,12 +84,16 @@ class TestCheckOverflow: class TestGetQtArgs: + """Tests for get_args.""" @pytest.fixture def parser(self, mocker): + """Fixture to provide an argparser. + + Monkey-patches .exit() of the argparser so it doesn't exit on errors. + """ parser = qutebrowser.get_argparser() - # monkey-patch .exit() of the argparser so it doesn't exit. mocker.patch.object(parser, 'exit', side_effect=Exception) return parser From 96ddfd5b65d19f1aff1d1e80553bccd73dbd1e86 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Apr 2015 07:55:59 -0300 Subject: [PATCH 04/11] Parametrize TestSplitCount in test_basekeyparser As pointed out by @The-Compiler --- tests/keyinput/test_basekeyparser.py | 50 +++++++++------------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/tests/keyinput/test_basekeyparser.py b/tests/keyinput/test_basekeyparser.py index 7164bffbd..8206a8194 100644 --- a/tests/keyinput/test_basekeyparser.py +++ b/tests/keyinput/test_basekeyparser.py @@ -63,44 +63,26 @@ class TestSplitCount: """Test the _split_count method. - Attributes: - kp: The BaseKeyParser we're testing. + Class Attributes: + TESTS: list of parameters for the tests, as tuples of + (input_key, supports_count, expected) """ - @pytest.fixture(autouse=True) - def setup(self): - self.kp = basekeyparser.BaseKeyParser(0, supports_count=True) + TESTS = [ + ('10', True, (10, '')), + ('10foo', True, (10, 'foo')), + ('-1foo', True, (None, '-1foo')), + ('10e4foo', True, (10, 'e4foo')), + ('foo', True, (None, 'foo')), + ('10foo', False, (None, '10foo')), + ] - def test_onlycount(self): + @pytest.mark.parametrize('input_key, supports_count, expected', TESTS) + def test_splitcount(self, input_key, supports_count, expected): """Test split_count with only a count.""" - self.kp._keystring = '10' - assert self.kp._split_count() == (10, '') - - def test_normalcount(self): - """Test split_count with count and text.""" - self.kp._keystring = '10foo' - assert self.kp._split_count() == (10, 'foo') - - def test_minuscount(self): - """Test split_count with a negative count.""" - self.kp._keystring = '-1foo' - assert self.kp._split_count() == (None, '-1foo') - - def test_expcount(self): - """Test split_count with an exponential count.""" - self.kp._keystring = '10e4foo' - assert self.kp._split_count() == (10, 'e4foo') - - def test_nocount(self): - """Test split_count with only a command.""" - self.kp._keystring = 'foo' - assert self.kp._split_count() == (None, 'foo') - - def test_nosupport(self): - """Test split_count with a count when counts aren't supported.""" - self.kp._supports_count = False - self.kp._keystring = '10foo' - assert self.kp._split_count() == (None, '10foo') + kp = basekeyparser.BaseKeyParser(0, supports_count=supports_count) + kp._keystring = input_key + assert kp._split_count() == expected @pytest.mark.usefixtures('fake_keyconfig', 'mock_timer') From 55e3645131fcc1cb117d7b9e17e72c655e56f2ba Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Apr 2015 18:13:13 -0300 Subject: [PATCH 05/11] Add comment to test samples in test_basekeyparser --- tests/keyinput/test_basekeyparser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/keyinput/test_basekeyparser.py b/tests/keyinput/test_basekeyparser.py index 8206a8194..29d556ac5 100644 --- a/tests/keyinput/test_basekeyparser.py +++ b/tests/keyinput/test_basekeyparser.py @@ -69,6 +69,7 @@ class TestSplitCount: """ TESTS = [ + # (input_key, supports_count, expected) ('10', True, (10, '')), ('10foo', True, (10, 'foo')), ('-1foo', True, (None, '-1foo')), From 253f3b2cd7e99776aa33c3e2ad165554fa5942cd Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Apr 2015 18:40:56 -0300 Subject: [PATCH 06/11] Use namedtuple and parametrized fixture for TestSplit As discussed in the PR, this greatly improves legibility --- tests/misc/test_split.py | 58 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/tests/misc/test_split.py b/tests/misc/test_split.py index e926368e0..284a406be 100644 --- a/tests/misc/test_split.py +++ b/tests/misc/test_split.py @@ -18,6 +18,7 @@ # along with qutebrowser. If not, see . """Tests for qutebrowser.misc.split.""" +import collections import pytest @@ -29,7 +30,7 @@ from qutebrowser.misc import split # Format: input/split|output|without|keep/split|output|with|keep/ -test_data = r""" +test_data_str = r""" one two/one|two/one| two/ one "two three" four/one|two three|four/one| "two three"| four/ one 'two three' four/one|two three|four/one| 'two three'| four/ @@ -103,36 +104,53 @@ foo\ bar/foo bar/foo\ bar/ áéíóú/áéíóú/áéíóú/ """ -test_data_lines = test_data.strip().splitlines() + +def _parse_split_test_data_str(): + """ + Parse the test data set into a namedtuple to use in tests. + + Returns: + A list of namedtuples with str attributes: input, keep, no_keep + """ + tuple_class = collections.namedtuple('TestCase', 'input, keep, no_keep') + + result = [] + for line in test_data_str.splitlines(): + if not line: + continue + data = line.split('/') + item = tuple_class(input=data[0], keep=data[1].split('|'), + no_keep=data[2].split('|')) + result.append(item) + return result class TestSplit: """Test split.""" - @pytest.mark.parametrize('cmd, out', - [case.split('/')[:-2] - for case in test_data_lines]) - def test_split(self, cmd, out): + @pytest.fixture(params=_parse_split_test_data_str()) + def split_test_case(self, request): + """ + Fixture that will automatically parametrize all tests the depend on it + using the parsed test case data. + """ + return request.param + + def test_split(self, split_test_case): """Test splitting.""" - items = split.split(cmd) - assert items == out.split('|') + items = split.split(split_test_case.input) + assert items == split_test_case.keep - @pytest.mark.parametrize('cmd', - [case.split('/')[0] - for case in test_data_lines]) - def test_split_keep_original(self, cmd): + def test_split_keep_original(self, split_test_case): """Test if splitting with keep=True yields the original string.""" - items = split.split(cmd, keep=True) - assert ''.join(items) == cmd + items = split.split(split_test_case.input, keep=True) + assert ''.join(items) == split_test_case.input - @pytest.mark.parametrize('cmd, _mid, out', - [case.split('/')[:-1] - for case in test_data_lines]) - def test_split_keep(self, cmd, _mid, out): + def test_split_keep(self, split_test_case): """Test splitting with keep=True.""" - items = split.split(cmd, keep=True) - assert items == out.split('|') + items = split.split(split_test_case.input, keep=True) + assert items == split_test_case.no_keep class TestSimpleSplit: From 6f1e830aba5c58b7863f942ba003a05e97526734 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Apr 2015 18:44:40 -0300 Subject: [PATCH 07/11] Parametrize test_str_split_maxsplit As suggested by @hackebrot --- tests/misc/test_split.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/misc/test_split.py b/tests/misc/test_split.py index 284a406be..75c485937 100644 --- a/tests/misc/test_split.py +++ b/tests/misc/test_split.py @@ -170,18 +170,12 @@ class TestSimpleSplit: """Test if the behavior matches str.split.""" assert split.simple_split(test) == test.rstrip().split() - def test_str_split_maxsplit_1(self): - """Test if the behavior matches str.split with maxsplit=1.""" - s = "foo bar baz" - actual = split.simple_split(s, maxsplit=1) - expected = s.rstrip().split(maxsplit=1) - assert actual == expected - - def test_str_split_maxsplit_0(self): - """Test if the behavior matches str.split with maxsplit=0.""" - s = " foo bar baz " - actual = split.simple_split(s, maxsplit=0) - expected = s.rstrip().split(maxsplit=0) + @pytest.mark.parametrize('s, maxsplit', + [("foo bar baz", 1), (" foo bar baz ", 0)]) + def test_str_split_maxsplit(self, s, maxsplit): + """Test if the behavior matches str.split with given maxsplit.""" + actual = split.simple_split(s, maxsplit=maxsplit) + expected = s.rstrip().split(maxsplit=maxsplit) assert actual == expected @pytest.mark.parametrize('test, expected', TESTS.items()) From 29c51c288b01b50062483ac96a90d569f7cad68c Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 9 Apr 2015 18:47:25 -0300 Subject: [PATCH 08/11] Fix small typo in docstring --- qutebrowser/misc/split.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/misc/split.py b/qutebrowser/misc/split.py index bd1904763..b763d8246 100644 --- a/qutebrowser/misc/split.py +++ b/qutebrowser/misc/split.py @@ -127,7 +127,7 @@ def split(s, keep=False): """Split a string via ShellLexer. Args: - keep: Whether to keep are special chars in the split output. + keep: Whether to keep special chars in the split output. """ lexer = ShellLexer(s) lexer.keep = keep From f4c46ec1c5b699f1b9c2bf9be247ba1a35a6e143 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 10 Apr 2015 18:22:02 -0300 Subject: [PATCH 09/11] Improve test legibility in TestCheckOverflow Created OverflowTestCases which is responsible to provide data for the tests --- tests/utils/test_qtutils.py | 44 +++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/tests/utils/test_qtutils.py b/tests/utils/test_qtutils.py index e3c5478f8..290f6dad3 100644 --- a/tests/utils/test_qtutils.py +++ b/tests/utils/test_qtutils.py @@ -27,9 +27,9 @@ from qutebrowser import qutebrowser from qutebrowser.utils import qtutils -class TestCheckOverflow: - - """Test check_overflow. +class OverflowTestCases: + """ + Provides test data for overflow checking. Class attributes: INT32_MIN: Minimum valid value for a signed int32. @@ -59,24 +59,47 @@ class TestCheckOverflow: (float(INT64_MAX + 1), INT64_MAX)], } - @pytest.mark.parametrize('ctype, val', [(ctype, val) for ctype, vals in - GOOD_VALUES.items() for val in - vals]) + @classmethod + def iter_good_values(cls): + """ + Yields pairs of (c data type, value) which should pass overflow + checking. + """ + for ctype, values in cls.GOOD_VALUES.items(): + for value in values: + yield ctype, value + + @classmethod + def iter_bad_values(cls): + """ + Yields pairs of (c type, value, repl) for values which don't pass + overflow checking, and value they should be replaced with if overflow + checking should not be fatal. + """ + for ctype, values in cls.BAD_VALUES.items(): + for value, repl in values: + yield ctype, value, repl + + +class TestCheckOverflow: + """Test check_overflow. + """ + + @pytest.mark.parametrize('ctype, val', OverflowTestCases.iter_good_values()) def test_good_values(self, ctype, val): """Test values which are inside bounds.""" qtutils.check_overflow(val, ctype) @pytest.mark.parametrize('ctype, val', - [(ctype, val) for ctype, vals in - BAD_VALUES.items() for (val, _) in vals]) + [(ctype, val) for (ctype, val, _) in + OverflowTestCases.iter_bad_values()]) def test_bad_values_fatal(self, ctype, val): """Test values which are outside bounds with fatal=True.""" with pytest.raises(OverflowError): qtutils.check_overflow(val, ctype) @pytest.mark.parametrize('ctype, val, repl', - [(ctype, val, repl) for ctype, vals in - BAD_VALUES.items() for (val, repl) in vals]) + OverflowTestCases.iter_bad_values()) def test_bad_values_nonfatal(self, ctype, val, repl): """Test values which are outside bounds with fatal=False.""" newval = qtutils.check_overflow(val, ctype, fatal=False) @@ -84,7 +107,6 @@ class TestCheckOverflow: class TestGetQtArgs: - """Tests for get_args.""" @pytest.fixture From 6ae94d6f49273cac07cdefbec69968c691803a99 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 13 Apr 2015 18:20:40 -0300 Subject: [PATCH 10/11] Create module overflow_test_cases As suggested by @The-Compiler --- tests/utils/overflow_test_cases.py | 70 ++++++++++++++++++++++++++++++ tests/utils/test_qtutils.py | 62 +++----------------------- 2 files changed, 75 insertions(+), 57 deletions(-) create mode 100644 tests/utils/overflow_test_cases.py diff --git a/tests/utils/overflow_test_cases.py b/tests/utils/overflow_test_cases.py new file mode 100644 index 000000000..2801c1b72 --- /dev/null +++ b/tests/utils/overflow_test_cases.py @@ -0,0 +1,70 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2014-2015 Florian Bruhin (The Compiler) +# +# 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 . + +""" +Provides test data for overflow checking. + +Module attributes: + INT32_MIN: Minimum valid value for a signed int32. + INT32_MAX: Maximum valid value for a signed int32. + INT64_MIN: Minimum valid value for a signed int64. + INT64_MAX: Maximum valid value for a signed int64. + GOOD_VALUES: A dict of types mapped to a list of good values. + BAD_VALUES: A dict of types mapped to a list of bad values. +""" + +INT32_MIN = -(2 ** 31) +INT32_MAX = 2 ** 31 - 1 +INT64_MIN = -(2 ** 63) +INT64_MAX = 2 ** 63 - 1 + +GOOD_VALUES = { + 'int': [-1, 0, 1, 23.42, INT32_MIN, INT32_MAX], + 'int64': [-1, 0, 1, 23.42, INT64_MIN, INT64_MAX], +} + +BAD_VALUES = { + 'int': [(INT32_MIN - 1, INT32_MIN), + (INT32_MAX + 1, INT32_MAX), + (float(INT32_MAX + 1), INT32_MAX)], + 'int64': [(INT64_MIN - 1, INT64_MIN), + (INT64_MAX + 1, INT64_MAX), + (float(INT64_MAX + 1), INT64_MAX)], +} + + +def iter_good_values(): + """ + Yields pairs of (c data type, value) which should pass overflow + checking. + """ + for ctype, values in GOOD_VALUES.items(): + for value in values: + yield ctype, value + + +def iter_bad_values(): + """ + Yields pairs of (c type, value, repl) for values which don't pass + overflow checking, and a value they should be replaced with if overflow + checking should not be fatal. + """ + for ctype, values in BAD_VALUES.items(): + for value, repl in values: + yield ctype, value, repl diff --git a/tests/utils/test_qtutils.py b/tests/utils/test_qtutils.py index 290f6dad3..07633e46a 100644 --- a/tests/utils/test_qtutils.py +++ b/tests/utils/test_qtutils.py @@ -25,81 +25,29 @@ import pytest from qutebrowser import qutebrowser from qutebrowser.utils import qtutils - - -class OverflowTestCases: - """ - Provides test data for overflow checking. - - Class attributes: - INT32_MIN: Minimum valid value for a signed int32. - INT32_MAX: Maximum valid value for a signed int32. - INT64_MIN: Minimum valid value for a signed int64. - INT64_MAX: Maximum valid value for a signed int64. - GOOD_VALUES: A dict of types mapped to a list of good values. - BAD_VALUES: A dict of types mapped to a list of bad values. - """ - - INT32_MIN = -(2 ** 31) - INT32_MAX = 2 ** 31 - 1 - INT64_MIN = -(2 ** 63) - INT64_MAX = 2 ** 63 - 1 - - GOOD_VALUES = { - 'int': [-1, 0, 1, 23.42, INT32_MIN, INT32_MAX], - 'int64': [-1, 0, 1, 23.42, INT64_MIN, INT64_MAX], - } - - BAD_VALUES = { - 'int': [(INT32_MIN - 1, INT32_MIN), - (INT32_MAX + 1, INT32_MAX), - (float(INT32_MAX + 1), INT32_MAX)], - 'int64': [(INT64_MIN - 1, INT64_MIN), - (INT64_MAX + 1, INT64_MAX), - (float(INT64_MAX + 1), INT64_MAX)], - } - - @classmethod - def iter_good_values(cls): - """ - Yields pairs of (c data type, value) which should pass overflow - checking. - """ - for ctype, values in cls.GOOD_VALUES.items(): - for value in values: - yield ctype, value - - @classmethod - def iter_bad_values(cls): - """ - Yields pairs of (c type, value, repl) for values which don't pass - overflow checking, and value they should be replaced with if overflow - checking should not be fatal. - """ - for ctype, values in cls.BAD_VALUES.items(): - for value, repl in values: - yield ctype, value, repl +import overflow_test_cases class TestCheckOverflow: """Test check_overflow. """ - @pytest.mark.parametrize('ctype, val', OverflowTestCases.iter_good_values()) + @pytest.mark.parametrize('ctype, val', + overflow_test_cases.iter_good_values()) def test_good_values(self, ctype, val): """Test values which are inside bounds.""" qtutils.check_overflow(val, ctype) @pytest.mark.parametrize('ctype, val', [(ctype, val) for (ctype, val, _) in - OverflowTestCases.iter_bad_values()]) + overflow_test_cases.iter_bad_values()]) def test_bad_values_fatal(self, ctype, val): """Test values which are outside bounds with fatal=True.""" with pytest.raises(OverflowError): qtutils.check_overflow(val, ctype) @pytest.mark.parametrize('ctype, val, repl', - OverflowTestCases.iter_bad_values()) + overflow_test_cases.iter_bad_values()) def test_bad_values_nonfatal(self, ctype, val, repl): """Test values which are outside bounds with fatal=False.""" newval = qtutils.check_overflow(val, ctype, fatal=False) From ba678e29fbba687c7eb7dae05f934d203dd18c3a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 14 Apr 2015 07:00:56 +0200 Subject: [PATCH 11/11] Fix lint. --- tests/misc/test_split.py | 7 ++++--- tests/utils/overflow_test_cases.py | 14 +++++++------- tests/utils/test_qtutils.py | 5 +++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/misc/test_split.py b/tests/misc/test_split.py index 75c485937..65fa218b1 100644 --- a/tests/misc/test_split.py +++ b/tests/misc/test_split.py @@ -131,9 +131,10 @@ class TestSplit: @pytest.fixture(params=_parse_split_test_data_str()) def split_test_case(self, request): - """ - Fixture that will automatically parametrize all tests the depend on it - using the parsed test case data. + """Fixture to automatically parametrize all depending tests. + + It will use the test data from test_data_str, parsed using + _parse_split_test_data_str(). """ return request.param diff --git a/tests/utils/overflow_test_cases.py b/tests/utils/overflow_test_cases.py index 2801c1b72..08e6ae7a8 100644 --- a/tests/utils/overflow_test_cases.py +++ b/tests/utils/overflow_test_cases.py @@ -50,9 +50,9 @@ BAD_VALUES = { def iter_good_values(): - """ - Yields pairs of (c data type, value) which should pass overflow - checking. + """Yield "good" (C data type, value) tuples. + + Those should pass overflow checking. """ for ctype, values in GOOD_VALUES.items(): for value in values: @@ -60,10 +60,10 @@ def iter_good_values(): def iter_bad_values(): - """ - Yields pairs of (c type, value, repl) for values which don't pass - overflow checking, and a value they should be replaced with if overflow - checking should not be fatal. + """Yield pairs of "bad" (C type, value, repl) tuples. + + Theose should not pass overflow checking. The third value is the value they + should be replaced with if overflow checking should not be fatal. """ for ctype, values in BAD_VALUES.items(): for value, repl in values: diff --git a/tests/utils/test_qtutils.py b/tests/utils/test_qtutils.py index 07633e46a..85a99c2f4 100644 --- a/tests/utils/test_qtutils.py +++ b/tests/utils/test_qtutils.py @@ -29,8 +29,8 @@ import overflow_test_cases class TestCheckOverflow: - """Test check_overflow. - """ + + """Test check_overflow.""" @pytest.mark.parametrize('ctype, val', overflow_test_cases.iter_good_values()) @@ -55,6 +55,7 @@ class TestCheckOverflow: class TestGetQtArgs: + """Tests for get_args.""" @pytest.fixture