1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
# SPDX-FileCopyrightText: Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
import string
import functools
import operator
import pytest
from qutebrowser.qt.core import QUrl
from qutebrowser.utils import usertypes
import qutebrowser.browser.hints
@pytest.fixture(autouse=True)
def setup(win_registry, mode_manager):
pass
@pytest.fixture
def tabbed_browser(tabbed_browser_stubs, web_tab):
tb = tabbed_browser_stubs[0]
tb.widget.tabs = [web_tab]
tb.widget.current_index = 1
tb.widget.cur_url = QUrl('https://www.example.com/')
web_tab.container.expose() # No elements found if we don't do this.
return tb
def test_show_benchmark(benchmark, tabbed_browser, qtbot, mode_manager):
"""Benchmark showing/drawing of hint labels."""
tab = tabbed_browser.widget.tabs[0]
with qtbot.wait_signal(tab.load_finished):
tab.load_url(QUrl('qute://testdata/data/hints/benchmark.html'))
manager = qutebrowser.browser.hints.HintManager(win_id=0)
def bench():
with qtbot.wait_signal(mode_manager.entered):
manager.start()
with qtbot.wait_signal(mode_manager.left):
mode_manager.leave(usertypes.KeyMode.hint)
benchmark(bench)
def test_match_benchmark(benchmark, tabbed_browser, qtbot, mode_manager, qapp,
config_stub):
"""Benchmark matching of hint labels."""
tab = tabbed_browser.widget.tabs[0]
with qtbot.wait_signal(tab.load_finished):
tab.load_url(QUrl('qute://testdata/data/hints/benchmark.html'))
config_stub.val.hints.scatter = False
manager = qutebrowser.browser.hints.HintManager(win_id=0)
with qtbot.wait_signal(mode_manager.entered):
manager.start()
def bench():
manager.handle_partial_key('a')
qapp.processEvents()
manager.handle_partial_key('')
qapp.processEvents()
benchmark(bench)
with qtbot.wait_signal(mode_manager.left):
mode_manager.leave(usertypes.KeyMode.hint)
@pytest.mark.parametrize('min_len', [0, 3])
@pytest.mark.parametrize('num_chars', [5, 9])
@pytest.mark.parametrize('num_elements', [*range(1, 26), 125])
def test_scattered_hints_count(min_len, num_chars, num_elements):
"""Test scattered hints function.
Tests many properties from an invocation of _hint_scattered, including
1. Hints must be unique
2. There can only be two hint lengths, only 1 apart
3. There are no unique prefixes for long hints, such as 'la' with no 'l<x>'
"""
manager = qutebrowser.browser.hints.HintManager(win_id=0)
chars = string.ascii_lowercase[:num_chars]
hints = manager._hint_scattered(min_len, chars,
list(range(num_elements)))
# Check if hints are unique
assert len(hints) == len(set(hints))
# Check if any hints are shorter than min_len
assert not any(x for x in hints if len(x) < min_len)
# Check we don't have more than 2 link lengths
# Eg: 'a' 'bc' and 'def' cannot be in the same hint string
hint_lens = {len(h) for h in hints}
assert len(hint_lens) <= 2
if len(hint_lens) == 2:
# Check if hint_lens are more than 1 apart
# Eg: 'abc' and 'd' cannot be in the same hint sequence, but
# 'ab' and 'c' can
assert abs(functools.reduce(operator.sub, hint_lens)) <= 1
longest_hint_len = max(hint_lens)
shortest_hint_len = min(hint_lens)
longest_hints = [x for x in hints if len(x) == longest_hint_len]
if min_len < max(hint_lens) - 1:
# Check if we have any unique prefixes. For example, 'la'
# alone, with no other 'l<x>'
count_map = {}
for x in longest_hints:
prefix = x[:-1]
count_map[prefix] = count_map.get(prefix, 0) + 1
assert all(e != 1 for e in count_map.values())
# Check that the longest hint length isn't too long
if longest_hint_len > min_len and longest_hint_len > 1:
assert num_chars ** (longest_hint_len - 1) < num_elements
# Check longest hint is not too short
assert num_chars ** longest_hint_len >= num_elements
if longest_hint_len > min_len and longest_hint_len > 1:
# Check that the longest hint length isn't too long
assert num_chars ** (longest_hint_len - 1) < num_elements
if shortest_hint_len == longest_hint_len:
# Check that we really couldn't use any short links
assert ((num_chars ** longest_hint_len) - num_elements <
len(chars) - 1)
|