diff options
Diffstat (limited to 'tests')
20 files changed, 353 insertions, 204 deletions
diff --git a/tests/end2end/data/prefers_reduced_motion.html b/tests/end2end/data/prefers_reduced_motion.html new file mode 100644 index 000000000..a37d43864 --- /dev/null +++ b/tests/end2end/data/prefers_reduced_motion.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Prefers reduced motion test</title> + <style> +#reduce-text { + display: none; +} +#no-preference-text { + display: none; +} + +@media (prefers-reduced-motion: no-preference) { + #no-preference-text { + display: inline; + } + #missing-support-text { + display: none; + } +} + +@media (prefers-reduced-motion: reduce) { + #reduce-text { + display: inline; + } + #missing-support-text { + display: none; + } +} + </style> + </head> + <body> + <p id="reduce-text">Reduced motion preference detected.</p> + <p id="no-preference-text">No preference detected.</p> + <p id="missing-support-text">Preference support missing.</p> + </body> +</html> diff --git a/tests/end2end/features/downloads.feature b/tests/end2end/features/downloads.feature index 6448e7809..dfdb24704 100644 --- a/tests/end2end/features/downloads.feature +++ b/tests/end2end/features/downloads.feature @@ -79,7 +79,7 @@ Feature: Downloading things from a website. And I set downloads.location.prompt to true And I open data/downloads/issue1243.html And I hint with args "links download" and follow a - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='qutebrowser-download' mode=PromptMode.download option=None text=* title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='qutebrowser-download' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log Then the error "Download error: No handler found for qute://" should be shown And "NotFoundError while handling qute://* URL" should be logged @@ -88,7 +88,7 @@ Feature: Downloading things from a website. And I set downloads.location.prompt to true And I open data/data_link.html And I hint with args "links download" and follow s - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='download.pdf' mode=PromptMode.download option=None text=* title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='download.pdf' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log And I run :mode-leave Then no crash should happen @@ -96,7 +96,7 @@ Feature: Downloading things from a website. When I set downloads.location.suggestion to filename And I set downloads.location.prompt to true And I open data/downloads/download.bin in a new window without waiting - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> *" in the log And I run :window-only And I run :mode-leave Then no crash should happen @@ -164,7 +164,7 @@ Feature: Downloading things from a website. Scenario: Downloading a file to a reserved path When I set downloads.location.prompt to true And I open data/downloads/download.bin without waiting - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download option=None text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log And I run :prompt-accept COM1 And I run :mode-leave Then the error "Invalid filename" should be shown @@ -173,7 +173,7 @@ Feature: Downloading things from a website. Scenario: Downloading a file to a drive-relative working directory When I set downloads.location.prompt to true And I open data/downloads/download.bin without waiting - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download option=None text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/downloads/download.bin</b>' title='Save file to:'>, *" in the log And I run :prompt-accept C:foobar And I run :mode-leave Then the error "Invalid filename" should be shown @@ -247,14 +247,14 @@ Feature: Downloading things from a website. Scenario: :download with a filename and directory which doesn't exist When I run :download --dest (tmpdir)(dirsep)downloads(dirsep)somedir(dirsep)file http://localhost:(port)/data/downloads/download.bin - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=PromptMode.yesno option=None text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> option=None text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log And I run :prompt-accept yes And I wait until the download is finished Then the downloaded file somedir/file should exist Scenario: :download with a directory which doesn't exist When I run :download --dest (tmpdir)(dirsep)downloads(dirsep)somedir(dirsep) http://localhost:(port)/data/downloads/download.bin - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=PromptMode.yesno option=None text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> option=None text='<b>*</b> does not exist. Create it?' title='Create directory?'>, *" in the log And I run :prompt-accept yes And I wait until the download is finished Then the downloaded file somedir/download.bin should exist @@ -279,13 +279,13 @@ Feature: Downloading things from a website. When I set downloads.location.prompt to true And I open data/title.html And I run :download --mhtml - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download option=None text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log And I run :prompt-accept And I wait for "File successfully written." in the log And I run :download --mhtml - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download option=None text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text='Please enter a location for <b>http://localhost:*/data/title.html</b>' title='Save file to:'>, *" in the log And I run :prompt-accept - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=PromptMode.yesno option=None text='<b>*</b> already exists. Overwrite?' title='Overwrite existing file?'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=None mode=<PromptMode.yesno: 1> option=None text='<b>*</b> already exists. Overwrite?' title='Overwrite existing file?'>, *" in the log And I run :prompt-accept yes And I wait for "File successfully written." in the log Then the downloaded file Test title.mhtml should exist @@ -655,9 +655,9 @@ Feature: Downloading things from a website. Scenario: Answering a question for a cancelled download (#415) When I set downloads.location.prompt to true And I run :download http://localhost:(port)/data/downloads/download.bin - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download option=None text=* title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log And I run :download http://localhost:(port)/data/downloads/download2.bin - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=PromptMode.download option=None text=* title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log And I run :download-cancel with count 2 And I run :prompt-accept And I wait until the download is finished diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index 3951dd2b0..e6a02e038 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -196,7 +196,7 @@ Feature: Various utility commands. # We can't use "When I open" because we don't want to wait for load # finished When I run :open http://localhost:(port)/redirect-later?delay=-1 - And I wait for "emitting: cur_load_status_changed(*loading*) (tab *)" in the log + And I wait for "emitting: cur_load_status_changed(<LoadStatus.loading: *>) (tab *)" in the log And I wait 1s And I run :stop And I open redirect-later-continue in a new tab diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index bb556df53..039434f1c 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -192,7 +192,7 @@ Feature: Special qute:// pages And I open data/misc/test.pdf without waiting And I wait for "[qute://pdfjs/*] PDF * (PDF.js: *)" in the log And I run :jseval document.getElementById("download").click() - And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=* mode=PromptMode.download option=None text=* title='Save file to:'>, *" in the log + And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=* mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log And I run :mode-leave Then no crash should happen diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py index f7b19b4b0..804ed40fe 100644 --- a/tests/end2end/features/test_downloads_bdd.py +++ b/tests/end2end/features/test_downloads_bdd.py @@ -28,7 +28,7 @@ bdd.scenarios('downloads.feature') PROMPT_MSG = ("Asking question <qutebrowser.utils.usertypes.Question " - "default={!r} mode=PromptMode.download option=None " + "default={!r} mode=<PromptMode.download: 5> option=None " "text=* title='Save file to:'>, *") diff --git a/tests/end2end/features/test_history_bdd.py b/tests/end2end/features/test_history_bdd.py index 3a44c2c11..f2e018b9f 100644 --- a/tests/end2end/features/test_history_bdd.py +++ b/tests/end2end/features/test_history_bdd.py @@ -33,6 +33,7 @@ def turn_on_sql_history(quteproc): cmd = ":debug-pyeval objects.debug_flags.remove('no-sql-history')" quteproc.send_cmd(cmd) quteproc.wait_for_load_finished_url('qute://pyeval') + quteproc.wait_for(message='INSERT INTO History *', category='sql') @bdd.then(bdd.parsers.parse("the query parameter {name} should be set to " @@ -50,6 +51,7 @@ def check_query(quteproc, name, value): @bdd.then(bdd.parsers.parse("the history should contain:\n{expected}")) def check_history(quteproc, server, tmpdir, expected): + quteproc.wait_for(message='INSERT INTO History *', category='sql') path = tmpdir / 'history' quteproc.send_cmd(':debug-dump-history "{}"'.format(path)) quteproc.wait_for(category='message', loglevel=logging.INFO, diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py index 0c0cfc50f..8555834e9 100644 --- a/tests/end2end/fixtures/quteprocess.py +++ b/tests/end2end/fixtures/quteprocess.py @@ -229,6 +229,10 @@ def is_ignored_chromium_message(line): # gpu_process_transport_factory.cc(1019)] Lost UI shared context. 'Lost UI shared context.', + # [20870:20908:0607/081717.652282:ERROR:block_files.cc(465)] Failed to + # open /tmp/qutebrowser-basedir-cg284f_m/data/webengine/GPUCache/data_2 + 'Failed to open *GPUCache*', + # Qt 5.12 # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70702 # [32123:32123:0923/224739.457307:ERROR:in_progress_cache_impl.cc(192)] @@ -330,6 +334,7 @@ def is_ignored_chromium_message(line): 'filtering (maybe)?'), ('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : ' 'DoEndSharedImageAccessCHROMIUM: bound texture is not a shared image'), + 'Unable to map Index file', # WebRTC with Qt 5.13 / 5.14 'Failed to query stereo recording.', diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py index 97c04eb0d..b860feed0 100644 --- a/tests/end2end/test_invocations.py +++ b/tests/end2end/test_invocations.py @@ -752,6 +752,30 @@ def test_dark_mode_mathml(quteproc_new, request, qtbot): ) +@testutils.qt514 +@pytest.mark.parametrize('value, preference', [ + ('true', 'Reduced motion'), + ('false', 'No'), +]) +@pytest.mark.skipif( + utils.is_windows, + reason="Outcome on Windows depends on system settings", +) +def test_prefers_reduced_motion(quteproc_new, request, value, preference): + if not request.config.webengine: + pytest.skip("Skipped with QtWebKit") + + args = _base_args(request.config) + [ + '--temp-basedir', + '-s', 'content.prefers_reduced_motion', value, + ] + quteproc_new.start(args) + + quteproc_new.open_path('data/prefers_reduced_motion.html') + content = quteproc_new.get_content() + assert content == f"{preference} preference detected." + + def test_unavailable_backend(request, quteproc_new): """Test starting with a backend which isn't available. @@ -802,4 +826,3 @@ def test_json_logging_without_debug(request, quteproc_new, runtime_tmpdir): quteproc_new.exit_expected = True quteproc_new.start(args, env={'XDG_RUNTIME_DIR': str(runtime_tmpdir)}) assert not quteproc_new.is_running() - assert not quteproc_new.captured_log diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py index 7106698be..cd3778b8a 100644 --- a/tests/helpers/fixtures.py +++ b/tests/helpers/fixtures.py @@ -639,15 +639,6 @@ def short_tmpdir(): yield py.path.local(tdir) # pylint: disable=no-member -@pytest.fixture -def init_sql(data_tmpdir): - """Initialize the SQL module, and shut it down after the test.""" - path = str(data_tmpdir / 'test.db') - sql.init(path) - yield - sql.close() - - class ModelValidator: """Validates completion models.""" @@ -682,12 +673,20 @@ def download_stub(win_registry, tmpdir, stubs): @pytest.fixture -def web_history(fake_save_manager, tmpdir, init_sql, config_stub, stubs, +def database(data_tmpdir): + """Create a Database object.""" + db = sql.Database(str(data_tmpdir / 'test.db')) + yield db + db.close() + + +@pytest.fixture +def web_history(fake_save_manager, tmpdir, database, config_stub, stubs, monkeypatch): """Create a WebHistory object.""" config_stub.val.completion.timestamp_format = '%Y-%m-%d' config_stub.val.completion.web_history.max_items = -1 - web_history = history.WebHistory(stubs.FakeHistoryProgress()) + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) monkeypatch.setattr(history, 'web_history', web_history) return web_history diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py index 1a46c5be0..7906d385c 100644 --- a/tests/unit/browser/test_history.py +++ b/tests/unit/browser/test_history.py @@ -31,7 +31,7 @@ from qutebrowser.misc import sql, objects @pytest.fixture(autouse=True) -def prerequisites(config_stub, fake_save_manager, init_sql, fake_args): +def prerequisites(config_stub, fake_save_manager, fake_args): """Make sure everything is ready to initialize a WebHistory.""" config_stub.data = {'general': {'private-browsing': False}} @@ -311,14 +311,14 @@ class TestInit: @pytest.mark.parametrize('backend', [usertypes.Backend.QtWebEngine, usertypes.Backend.QtWebKit]) - def test_init(self, backend, qapp, tmpdir, monkeypatch, cleanup_init): + def test_init(self, backend, qapp, tmpdir, data_tmpdir, monkeypatch, cleanup_init): if backend == usertypes.Backend.QtWebKit: pytest.importorskip('PyQt5.QtWebKitWidgets') else: assert backend == usertypes.Backend.QtWebEngine monkeypatch.setattr(history.objects, 'backend', backend) - history.init(qapp) + history.init(data_tmpdir / f'test_init_{backend}', qapp) assert history.web_history.parent() is qapp try: @@ -368,44 +368,40 @@ class TestDump: class TestRebuild: - # FIXME: Some of those tests might be a bit misleading, as creating a new - # history.WebHistory will regenerate the completion either way with the SQL changes - # in v2.0.0 (because the user version changed from 0 -> 3). - # - # They should be revisited once we can actually create two independent sqlite - # databases and copy the data over, for a "real" test. - - def test_user_version(self, web_history, stubs, monkeypatch): + def test_user_version(self, database, stubs, monkeypatch): """Ensure that completion is regenerated if user_version changes.""" + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') - # User version always changes, so this won't work - # hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) - # assert list(hist2.completion) == [('example.com/1', '', 1)] + hist2 = history.WebHistory(database, progress=stubs.FakeHistoryProgress()) + assert list(hist2.completion) == [('example.com/1', '', 1)] - monkeypatch.setattr(sql, 'user_version_changed', lambda: True) + monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) - hist3 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist3 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist3.completion) == [ ('example.com/1', '', 1), ('example.com/2', '', 2), ] assert not hist3.metainfo['force_rebuild'] - def test_force_rebuild(self, web_history, stubs): + def test_force_rebuild(self, database, stubs): """Ensure that completion is regenerated if we force a rebuild.""" + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) web_history.completion.delete('url', 'example.com/2') - hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) - # User version always changes, so this won't work - # assert list(hist2.completion) == [('example.com/1', '', 1)] + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) + assert list(hist2.completion) == [('example.com/1', '', 1)] hist2.metainfo['force_rebuild'] = True - hist3 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist3 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist3.completion) == [ ('example.com/1', '', 1), ('example.com/2', '', 2), @@ -424,7 +420,8 @@ class TestRebuild: web_history.add_url(QUrl('http://example.org'), redirect=False, atime=2) - hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist2.completion) == [('http://example.com', '', 1)] def test_pattern_change_rebuild(self, config_stub, web_history, stubs): @@ -436,14 +433,16 @@ class TestRebuild: web_history.add_url(QUrl('http://example.org'), redirect=False, atime=2) - hist2 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist2.completion) == [ ('http://example.com', '', 1), ] config_stub.val.completion.web_history.exclude = [] - hist3 = history.WebHistory(progress=stubs.FakeHistoryProgress()) + hist3 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) assert list(hist3.completion) == [ ('http://example.com', '', 1), ('http://example.org', '', 2) @@ -454,37 +453,39 @@ class TestRebuild: web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2) # Trigger a completion rebuild - monkeypatch.setattr(sql, 'user_version_changed', lambda: True) + monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) progress = stubs.FakeHistoryProgress() - history.WebHistory(progress=progress) + history.WebHistory(web_history.database, progress=progress) assert progress._value == 2 assert progress._started assert progress._finished - def test_interrupted(self, stubs, web_history, monkeypatch): + def test_interrupted(self, stubs, database, monkeypatch): """If we interrupt the rebuilding process, force_rebuild should still be set.""" + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1) + web_history.completion.delete('url', 'example.com/1') progress = stubs.FakeHistoryProgress(raise_on_tick=True) # Trigger a completion rebuild - monkeypatch.setattr(sql, 'user_version_changed', lambda: True) + monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True) with pytest.raises(Exception, match='tick-tock'): - history.WebHistory(progress=progress) + history.WebHistory(web_history.database, progress=progress) assert web_history.metainfo['force_rebuild'] - # If we now try again, we should get another rebuild. But due to user_version - # always changing, we can't test this at the moment (see the FIXME in the - # docstring for details) + hist2 = history.WebHistory(web_history.database, + progress=stubs.FakeHistoryProgress()) + assert list(hist2.completion) == [('example.com/1', '', 1)] class TestCompletionMetaInfo: @pytest.fixture - def metainfo(self): - return history.CompletionMetaInfo() + def metainfo(self, database): + return history.CompletionMetaInfo(database) def test_contains_keyerror(self, metainfo): with pytest.raises(KeyError): @@ -507,27 +508,27 @@ class TestCompletionMetaInfo: metainfo['excluded_patterns'] = value assert metainfo['excluded_patterns'] == value - # FIXME: It'd be good to test those two things via WebHistory (and not just - # CompletionMetaInfo in isolation), but we can't do that right now - see the - # docstring of TestRebuild for details. - - def test_recovery_no_key(self, metainfo): - metainfo.delete('key', 'force_rebuild') + def test_recovery_no_key(self, caplog, database, stubs): + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) + web_history.metainfo.delete('key', 'force_rebuild') with pytest.raises(sql.BugError, match='No result for single-result query'): - metainfo['force_rebuild'] + web_history.metainfo['force_rebuild'] - metainfo.try_recover() - assert not metainfo['force_rebuild'] + with caplog.at_level(logging.WARNING): + web_history2 = history.WebHistory(database, stubs.FakeHistoryProgress()) + assert not web_history2.metainfo['force_rebuild'] - def test_recovery_no_table(self, metainfo): - sql.Query("DROP TABLE CompletionMetaInfo").run() + def test_recovery_no_table(self, caplog, database, stubs): + web_history = history.WebHistory(database, stubs.FakeHistoryProgress()) + web_history.metainfo.database.query("DROP TABLE CompletionMetaInfo").run() with pytest.raises(sql.BugError, match='no such table: CompletionMetaInfo'): - metainfo['force_rebuild'] + web_history.metainfo['force_rebuild'] - metainfo.try_recover() - assert not metainfo['force_rebuild'] + with caplog.at_level(logging.WARNING): + web_history2 = history.WebHistory(database, stubs.FakeHistoryProgress()) + assert not web_history2.metainfo['force_rebuild'] class TestHistoryProgress: diff --git a/tests/unit/browser/webengine/test_webenginetab.py b/tests/unit/browser/webengine/test_webenginetab.py index 274e216ba..3d8eec663 100644 --- a/tests/unit/browser/webengine/test_webenginetab.py +++ b/tests/unit/browser/webengine/test_webenginetab.py @@ -164,6 +164,45 @@ class TestWebengineScripts: assert scripts_helper.get_script().injectionPoint() == expected + @pytest.mark.parametrize('header1, header2, expected_names', [ + ( + ["// @namespace ns1", "// @name same"], + ["// @namespace ns2", "// @name same"], + ['GM-ns1/same', 'GM-ns2/same'], + ), + ( + ["// @name same"], + ["// @name same"], + ['GM-same', 'GM-same-2'], + ), + ( + ["// @name same"], + ["// @name sam"], + ['GM-same', 'GM-sam'], + ), + ]) + def test_greasemonkey_duplicate_name(self, scripts_helper, + header1, header2, expected_names): + template = """ + // ==UserScript== + {header} + // ==/UserScript== + """ + template = textwrap.dedent(template.lstrip('\n')) + + source1 = template.format(header="\n".join(header1)) + script1 = greasemonkey.GreasemonkeyScript.parse(source1) + source2 = template.format(header="\n".join(header2)) + script2 = greasemonkey.GreasemonkeyScript.parse(source2) + scripts_helper.inject([script1, script2]) + + names = [script.name() for script in scripts_helper.get_scripts()] + assert names == expected_names + + source3 = textwrap.dedent(template.lstrip('\n')).format(header="// @name other") + script3 = greasemonkey.GreasemonkeyScript.parse(source3) + scripts_helper.inject([script3]) + def test_notification_permission_workaround(): """Make sure the value for QWebEnginePage::Notifications is correct.""" diff --git a/tests/unit/completion/test_histcategory.py b/tests/unit/completion/test_histcategory.py index e0a12943b..cb37fb784 100644 --- a/tests/unit/completion/test_histcategory.py +++ b/tests/unit/completion/test_histcategory.py @@ -32,10 +32,11 @@ from qutebrowser.utils import usertypes @pytest.fixture -def hist(init_sql, config_stub): +def hist(data_tmpdir, config_stub): + db = sql.Database(str(data_tmpdir / 'test_histcategory.db')) config_stub.val.completion.timestamp_format = '%Y-%m-%d' config_stub.val.completion.web_history.max_items = -1 - return sql.SqlTable('CompletionHistory', ['url', 'title', 'last_atime']) + return sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime']) @pytest.mark.parametrize('pattern, before, after', [ @@ -99,7 +100,7 @@ def test_set_pattern(pattern, before, after, model_validator, hist): """Validate the filtering and sorting results of set_pattern.""" for row in before: hist.insert({'url': row[0], 'title': row[1], 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern(pattern) model_validator.validate(after) @@ -110,7 +111,7 @@ def test_set_pattern_repeated(model_validator, hist): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) hist.insert({'url': 'example.com/bar', 'title': 'title2', 'last_atime': 1}) hist.insert({'url': 'example.com/baz', 'title': 'title3', 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('b') @@ -143,7 +144,7 @@ def test_set_pattern_repeated(model_validator, hist): ], ids=['numbers', 'characters']) def test_set_pattern_long(hist, message_mock, caplog, pattern): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) with caplog.at_level(logging.ERROR): cat.set_pattern(pattern) msg = message_mock.getmsg(usertypes.MessageLevel.error) @@ -153,7 +154,7 @@ def test_set_pattern_long(hist, message_mock, caplog, pattern): @hypothesis.given(pat=strategies.text()) def test_set_pattern_hypothesis(hist, pat, caplog): hist.insert({'url': 'example.com/foo', 'title': 'title1', 'last_atime': 1}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) with caplog.at_level(logging.ERROR): cat.set_pattern(pat) @@ -202,7 +203,7 @@ def test_sorting(max_items, before, after, model_validator, hist, config_stub): for url, title, atime in before: timestamp = datetime.datetime.strptime(atime, '%Y-%m-%d').timestamp() hist.insert({'url': url, 'title': title, 'last_atime': timestamp}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('') model_validator.validate(after) @@ -211,7 +212,7 @@ def test_sorting(max_items, before, after, model_validator, hist, config_stub): def test_remove_rows(hist, model_validator): hist.insert({'url': 'foo', 'title': 'Foo', 'last_atime': 0}) hist.insert({'url': 'bar', 'title': 'Bar', 'last_atime': 0}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('') hist.delete('url', 'foo') @@ -227,7 +228,7 @@ def test_remove_rows_fetch(hist): 'title': [str(i) for i in range(300)], 'last_atime': [0] * 300, }) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) cat.set_pattern('') # sanity check that we didn't fetch everything up front @@ -245,20 +246,21 @@ def test_remove_rows_fetch(hist): ('%m/%d/%Y %H:%M', '02/27/2018 08:30'), ('', ''), ]) -def test_timestamp_fmt(fmt, expected, model_validator, config_stub, init_sql): +def test_timestamp_fmt(fmt, expected, model_validator, config_stub, data_tmpdir): """Validate the filtering and sorting results of set_pattern.""" config_stub.val.completion.timestamp_format = fmt - hist = sql.SqlTable('CompletionHistory', ['url', 'title', 'last_atime']) + db = sql.Database(str(data_tmpdir / 'test_timestamp_fmt.db')) + hist = sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime']) atime = datetime.datetime(2018, 2, 27, 8, 30) hist.insert({'url': 'foo', 'title': '', 'last_atime': atime.timestamp()}) - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) model_validator.set_model(cat) cat.set_pattern('') model_validator.validate([('foo', '', expected)]) def test_skip_duplicate_set(message_mock, caplog, hist): - cat = histcategory.HistoryCategory() + cat = histcategory.HistoryCategory(database=hist.database) cat.set_pattern('foo') cat.set_pattern('foobarbaz') msg = caplog.messages[-1] diff --git a/tests/unit/components/test_braveadblock.py b/tests/unit/components/test_braveadblock.py index 02f7c1074..fc50cb595 100644 --- a/tests/unit/components/test_braveadblock.py +++ b/tests/unit/components/test_braveadblock.py @@ -29,6 +29,7 @@ import pytest from qutebrowser.api.interceptor import ResourceType from qutebrowser.components import braveadblock from qutebrowser.components.utils import blockutils +from qutebrowser.utils import usertypes from helpers import testutils pytestmark = pytest.mark.usefixtures("qapp") @@ -417,3 +418,15 @@ def test_buggy_url_workaround_needed(ad_blocker, config_stub, easylist_easypriva request_type=resource_type_str ) assert result.matched + + +def test_corrupt_cache_handling(ad_blocker, message_mock, caplog): + ad_blocker._cache_path.write_text("blablub") + + with caplog.at_level(logging.ERROR): + ad_blocker.read_cache() + + msg = message_mock.getmsg(usertypes.MessageLevel.error) + assert msg.text == ( + "Reading adblock filter data failed (corrupted data?). " + "Please run :adblock-update.") diff --git a/tests/unit/components/test_hostblock.py b/tests/unit/components/test_hostblock.py index 8dd8d6dda..00a7a5f8f 100644 --- a/tests/unit/components/test_hostblock.py +++ b/tests/unit/components/test_hostblock.py @@ -279,7 +279,7 @@ def test_disabled_blocking_per_url(config_stub, host_blocker_factory): pattern = urlmatch.UrlPattern(example_com) config_stub.set_obj("content.blocking.enabled", False, pattern=pattern) - url = QUrl("blocked.example.com") + url = QUrl("https://blocked.example.com") host_blocker = host_blocker_factory() host_blocker._blocked_hosts.add(url.host()) @@ -563,3 +563,11 @@ def test_adblock_benchmark(data_tmpdir, benchmark, host_blocker_factory): assert blocker._blocked_hosts benchmark(lambda: blocker._is_blocked(url)) + + +def test_subdomain_blocking(config_stub, host_blocker_factory): + config_stub.val.content.blocking.method = "hosts" + config_stub.val.content.blocking.hosts.lists = None + host_blocker = host_blocker_factory() + host_blocker._blocked_hosts.add("example.com") + assert host_blocker._is_blocked(QUrl("https://subdomain.example.com")) diff --git a/tests/unit/config/test_configutils.py b/tests/unit/config/test_configutils.py index e06463bb4..e7ce15aff 100644 --- a/tests/unit/config/test_configutils.py +++ b/tests/unit/config/test_configutils.py @@ -300,29 +300,6 @@ def test_domain_lookup_sparse_benchmark(url, values, benchmark): benchmark(lambda: values.get_for_url(url)) -class TestWiden: - - @pytest.mark.parametrize('hostname, expected', [ - ('a.b.c', ['a.b.c', 'b.c', 'c']), - ('foobarbaz', ['foobarbaz']), - ('', []), - ('.c', ['.c', 'c']), - ('c.', ['c.']), - ('.c.', ['.c.', 'c.']), - (None, []), - ]) - def test_widen_hostnames(self, hostname, expected): - assert list(configutils._widened_hostnames(hostname)) == expected - - @pytest.mark.parametrize('hostname', [ - 'test.qutebrowser.org', - 'a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.z.y.z', - 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.c', - ]) - def test_bench_widen_hostnames(self, hostname, benchmark): - benchmark(lambda: list(configutils._widened_hostnames(hostname))) - - class TestFontFamilies: @pytest.mark.parametrize('family_str, expected', [ diff --git a/tests/unit/javascript/test_greasemonkey.py b/tests/unit/javascript/test_greasemonkey.py index 2bfb9ca83..17847816d 100644 --- a/tests/unit/javascript/test_greasemonkey.py +++ b/tests/unit/javascript/test_greasemonkey.py @@ -131,6 +131,20 @@ def test_no_name_with_fallback(): assert script.name == r"C:\COM1" +@pytest.mark.parametrize('properties, inc_counter, expected', [ + ([("name", "gorilla")], False, "GM-gorilla"), + ([("namespace", "apes"), ("name", "gorilla")], False, "GM-apes/gorilla"), + + ([("name", "gorilla")], True, "GM-gorilla-2"), + ([("namespace", "apes"), ("name", "gorilla")], True, "GM-apes/gorilla-2"), +]) +def test_full_name(properties, inc_counter, expected): + script = greasemonkey.GreasemonkeyScript(properties, code="") + if inc_counter: + script.dedup_suffix += 1 + assert script.full_name() == expected + + def test_bad_scheme(caplog): """qute:// isn't in the list of allowed schemes.""" _save_script("var nothing = true;\n", 'nothing.user.js') diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py index f6fa68869..80ab7513c 100644 --- a/tests/unit/misc/test_sql.py +++ b/tests/unit/misc/test_sql.py @@ -23,12 +23,12 @@ import pytest import hypothesis from hypothesis import strategies -from PyQt5.QtSql import QSqlError +from PyQt5.QtSql import QSqlDatabase, QSqlError, QSqlQuery from qutebrowser.misc import sql -pytestmark = pytest.mark.usefixtures('init_sql') +pytestmark = pytest.mark.usefixtures('data_tmpdir') class TestUserVersion: @@ -120,23 +120,23 @@ class TestSqlError: assert err.text() == "db text" -def test_init(): - sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_init_table(database): + database.table('Foo', ['name', 'val', 'lucky']) # should not error if table already exists - sql.SqlTable('Foo', ['name', 'val', 'lucky']) + database.table('Foo', ['name', 'val', 'lucky']) -def test_insert(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_insert(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}) with qtbot.wait_signal(table.changed): table.insert({'name': 'wan', 'val': 1, 'lucky': False}) -def test_insert_replace(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky'], - constraints={'name': 'PRIMARY KEY'}) +def test_insert_replace(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky'], + constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): table.insert({'name': 'one', 'val': 1, 'lucky': False}, replace=True) with qtbot.wait_signal(table.changed): @@ -147,8 +147,8 @@ def test_insert_replace(qtbot): table.insert({'name': 'one', 'val': 11, 'lucky': True}, replace=False) -def test_insert_batch(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_insert_batch(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) with qtbot.wait_signal(table.changed): table.insert_batch({'name': ['one', 'nine', 'thirteen'], @@ -160,9 +160,9 @@ def test_insert_batch(qtbot): ('thirteen', 13, True)] -def test_insert_batch_replace(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky'], - constraints={'name': 'PRIMARY KEY'}) +def test_insert_batch_replace(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky'], + constraints={'name': 'PRIMARY KEY'}) with qtbot.wait_signal(table.changed): table.insert_batch({'name': ['one', 'nine', 'thirteen'], @@ -185,8 +185,8 @@ def test_insert_batch_replace(qtbot): 'lucky': [True, True]}) -def test_iter(): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_iter(database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -205,15 +205,15 @@ def test_iter(): ([{"a": 2, "b": 5}, {"a": 1, "b": 6}, {"a": 3, "b": 4}], 'a', 'asc', -1, [(1, 6), (2, 5), (3, 4)]), ]) -def test_select(rows, sort_by, sort_order, limit, result): - table = sql.SqlTable('Foo', ['a', 'b']) +def test_select(rows, sort_by, sort_order, limit, result, database): + table = database.table('Foo', ['a', 'b']) for row in rows: table.insert(row) assert list(table.select(sort_by, sort_order, limit)) == result -def test_delete(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_delete(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -227,8 +227,8 @@ def test_delete(qtbot): assert not list(table) -def test_len(): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_len(database): + table = database.table('Foo', ['name', 'val', 'lucky']) assert len(table) == 0 table.insert({'name': 'one', 'val': 1, 'lucky': False}) assert len(table) == 1 @@ -238,15 +238,15 @@ def test_len(): assert len(table) == 3 -def test_bool(): - table = sql.SqlTable('Foo', ['name']) +def test_bool(database): + table = database.table('Foo', ['name']) assert not table table.insert({'name': 'one'}) assert table -def test_bool_benchmark(benchmark): - table = sql.SqlTable('Foo', ['number']) +def test_bool_benchmark(benchmark, database): + table = database.table('Foo', ['number']) # Simulate a history table table.create_index('NumberIndex', 'number') @@ -258,8 +258,8 @@ def test_bool_benchmark(benchmark): benchmark(run) -def test_contains(): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_contains(database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -279,8 +279,8 @@ def test_contains(): assert not val_query.run(val=10).value() -def test_delete_all(qtbot): - table = sql.SqlTable('Foo', ['name', 'val', 'lucky']) +def test_delete_all(qtbot, database): + table = database.table('Foo', ['name', 'val', 'lucky']) table.insert({'name': 'one', 'val': 1, 'lucky': False}) table.insert({'name': 'nine', 'val': 9, 'lucky': False}) table.insert({'name': 'thirteen', 'val': 13, 'lucky': True}) @@ -295,90 +295,118 @@ def test_version(): class TestSqlQuery: - def test_prepare_error(self): + def test_prepare_error(self, database): with pytest.raises(sql.BugError) as excinfo: - sql.Query('invalid') + database.query('invalid') expected = ('Failed to prepare query "invalid": "near "invalid": ' 'syntax error Unable to execute statement"') assert str(excinfo.value) == expected @pytest.mark.parametrize('forward_only', [True, False]) - def test_forward_only(self, forward_only): - q = sql.Query('SELECT 0 WHERE 0', forward_only=forward_only) + def test_forward_only(self, forward_only, database): + q = database.query('SELECT 0 WHERE 0', forward_only=forward_only) assert q.query.isForwardOnly() == forward_only - def test_iter_inactive(self): - q = sql.Query('SELECT 0') + def test_iter_inactive(self, database): + q = database.query('SELECT 0') with pytest.raises(sql.BugError, match='Cannot iterate inactive query'): next(iter(q)) - def test_iter_empty(self): - q = sql.Query('SELECT 0 AS col WHERE 0') + def test_iter_empty(self, database): + q = database.query('SELECT 0 AS col WHERE 0') q.run() with pytest.raises(StopIteration): next(iter(q)) - def test_iter(self): - q = sql.Query('SELECT 0 AS col') + def test_iter(self, database): + q = database.query('SELECT 0 AS col') q.run() result = next(iter(q)) assert result.col == 0 - def test_iter_multiple(self): - q = sql.Query('VALUES (1), (2), (3);') + def test_iter_multiple(self, database): + q = database.query('VALUES (1), (2), (3);') res = list(q.run()) assert len(res) == 3 assert res[0].column1 == 1 - def test_run_binding(self): - q = sql.Query('SELECT :answer') + def test_run_binding(self, database): + q = database.query('SELECT :answer') q.run(answer=42) assert q.value() == 42 - def test_run_missing_binding(self): - q = sql.Query('SELECT :answer') + def test_run_missing_binding(self, database): + q = database.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run() - def test_run_batch(self): - q = sql.Query('SELECT :answer') + def test_run_batch(self, database): + q = database.query('SELECT :answer') q.run_batch(values={'answer': [42]}) assert q.value() == 42 - def test_run_batch_missing_binding(self): - q = sql.Query('SELECT :answer') + def test_run_batch_missing_binding(self, database): + q = database.query('SELECT :answer') with pytest.raises(sql.BugError, match='Missing bound values!'): q.run_batch(values={}) - def test_value_missing(self): - q = sql.Query('SELECT 0 WHERE 0') + def test_value_missing(self, database): + q = database.query('SELECT 0 WHERE 0') q.run() - with pytest.raises(sql.BugError, - match='No result for single-result query'): + with pytest.raises(sql.BugError, match='No result for single-result query'): q.value() - def test_num_rows_affected_not_active(self): + def test_num_rows_affected_not_active(self, database): with pytest.raises(AssertionError): - q = sql.Query('SELECT 0') + q = database.query('SELECT 0') q.rows_affected() - def test_num_rows_affected_select(self): + def test_num_rows_affected_select(self, database): with pytest.raises(AssertionError): - q = sql.Query('SELECT 0') + q = database.query('SELECT 0') q.run() q.rows_affected() @pytest.mark.parametrize('condition', [0, 1]) - def test_num_rows_affected(self, condition): - table = sql.SqlTable('Foo', ['name']) + def test_num_rows_affected(self, condition, database): + table = database.table('Foo', ['name']) table.insert({'name': 'helloworld'}) - q = sql.Query(f'DELETE FROM Foo WHERE {condition}') + q = database.query(f'DELETE FROM Foo WHERE {condition}') q.run() assert q.rows_affected() == condition - def test_bound_values(self): - q = sql.Query('SELECT :answer') + def test_bound_values(self, database): + q = database.query('SELECT :answer') q.run(answer=42) assert q.bound_values() == {':answer': 42} + + +class TestTransaction: + + def test_successful_transaction(self, database): + my_table = database.table('my_table', ['column']) + with database.transaction(): + my_table.insert({'column': 1}) + my_table.insert({'column': 2}) + + db2 = QSqlDatabase.addDatabase('QSQLITE', 'db2') + db2.setDatabaseName(database.qt_database().databaseName()) + db2.open() + query = QSqlQuery(db2) + query.exec('select count(*) from my_table') + query.next() + assert query.record().value(0) == 0 + assert database.query('select count(*) from my_table').run().value() == 2 + + def test_failed_transaction(self, database): + my_table = database.table('my_table', ['column']) + try: + with database.transaction(): + my_table.insert({'column': 1}) + my_table.insert({'column': 2}) + raise Exception('something went horribly wrong') + except Exception: + pass + assert database.query('select count(*) from my_table').run().value() == 0 diff --git a/tests/unit/scripts/test_check_coverage.py b/tests/unit/scripts/test_check_coverage.py index efd35ce82..abb0969b6 100644 --- a/tests/unit/scripts/test_check_coverage.py +++ b/tests/unit/scripts/test_check_coverage.py @@ -98,7 +98,12 @@ def covtest(testdir, monkeypatch): # Check if coverage plugin is available res = testdir.runpytest('--version', '--version') assert res.ret == 0 + output = res.stderr.str() + if not output: + # pytest >= 7.0: https://github.com/pytest-dev/pytest/pull/8247 + output = res.stdout.str() + assert 'This is pytest version' in output if 'pytest-cov' not in output: pytest.skip("cov plugin not available") diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py index a5599c6c9..97ff268ca 100644 --- a/tests/unit/utils/test_urlutils.py +++ b/tests/unit/utils/test_urlutils.py @@ -778,3 +778,26 @@ class TestParseJavascriptUrl: pass else: assert parsed == source + + +class TestWiden: + + @pytest.mark.parametrize('hostname, expected', [ + ('a.b.c', ['a.b.c', 'b.c', 'c']), + ('foobarbaz', ['foobarbaz']), + ('', []), + ('.c', ['.c', 'c']), + ('c.', ['c.']), + ('.c.', ['.c.', 'c.']), + (None, []), + ]) + def test_widen_hostnames(self, hostname, expected): + assert list(urlutils.widened_hostnames(hostname)) == expected + + @pytest.mark.parametrize('hostname', [ + 'test.qutebrowser.org', + 'a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.z.y.z', + 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.c', + ]) + def test_bench_widen_hostnames(self, hostname, benchmark): + benchmark(lambda: list(urlutils.widened_hostnames(hostname))) diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py index 42b95a1a8..57adc883c 100644 --- a/tests/unit/utils/test_utils.py +++ b/tests/unit/utils/test_utils.py @@ -546,34 +546,6 @@ class TestIsEnum: assert not utils.is_enum(23) -class SomeEnum(enum.Enum): - - some_value = enum.auto() - - -class TestPyEnumStr: - - @pytest.fixture - def val(self): - return SomeEnum.some_value - - def test_fake_old_python_version(self, monkeypatch, val): - monkeypatch.setattr(sys, 'version_info', (3, 9, 2)) - assert utils.pyenum_str(val) == str(val) - - def test_fake_new_python_version(self, monkeypatch, val): - monkeypatch.setattr(sys, 'version_info', (3, 10, 0)) - assert utils.pyenum_str(val) == repr(val) - - def test_real_result(self, val): - assert utils.pyenum_str(val) == 'SomeEnum.some_value' - - @pytest.mark.skipif(sys.version_info[:2] < (3, 10), reason='Needs Python 3.10+') - def test_needed(self, val): - """Fail if this change gets revered before the final 3.10 release.""" - assert str(val) != 'SomeEnum.some_value' - - class TestRaises: """Test raises.""" |