qutebrowser/tests/unit/browser/test_qutescheme.py

168 lines
5.7 KiB
Python
Raw Normal View History

2017-02-08 09:28:04 +01:00
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2017 Imran Sobir
#
# 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/>.
2017-02-26 13:07:30 +01:00
import json
2017-02-27 18:37:24 +01:00
import os
2017-02-26 13:07:30 +01:00
import time
2017-02-09 11:44:51 +01:00
2017-02-08 09:28:04 +01:00
from PyQt5.QtCore import QUrl
2017-02-09 11:44:51 +01:00
import pytest
2017-02-08 09:28:04 +01:00
from qutebrowser.browser import history, qutescheme
from qutebrowser.utils import objreg
2017-02-27 18:37:24 +01:00
class TestJavascriptHandler:
"""Test the qute://javascript endpoint."""
# Tuples of fake JS files and their content.
js_files = [
('foo.js', "var a = 'foo';"),
('bar.js', "var a = 'bar';"),
]
@pytest.fixture(autouse=True)
def patch_read_file(self, monkeypatch):
"""Patch utils.read_file to return few fake JS files."""
def _read_file(path, binary=False):
2017-02-28 15:49:00 +01:00
"""Faked utils.read_file."""
2017-02-27 18:37:24 +01:00
assert not binary
for filename, content in self.js_files:
if path == os.path.join('javascript', filename):
return content
2017-03-09 17:47:12 +01:00
raise OSError("File not found {}!".format(path))
2017-02-27 18:37:24 +01:00
monkeypatch.setattr('qutebrowser.utils.utils.read_file', _read_file)
@pytest.mark.parametrize("filename, content", js_files)
def test_qutejavascript(self, filename, content):
url = QUrl("qute://javascript/{}".format(filename))
_mimetype, data = qutescheme.qute_javascript(url)
assert data == content
def test_qutejavascript_404(self):
2017-02-27 18:37:24 +01:00
url = QUrl("qute://javascript/404.js")
with pytest.raises(qutescheme.QuteSchemeOSError):
qutescheme.data_for_url(url)
2017-02-27 18:37:24 +01:00
def test_qutejavascript_empty_query(self):
url = QUrl("qute://javascript")
with pytest.raises(qutescheme.QuteSchemeError):
qutescheme.qute_javascript(url)
2017-02-08 09:28:04 +01:00
class TestHistoryHandler:
2017-02-09 11:44:51 +01:00
2017-02-08 09:28:04 +01:00
"""Test the qute://history endpoint."""
@pytest.fixture(scope="module")
def now(self):
return int(time.time())
2017-02-28 15:49:00 +01:00
@pytest.fixture
def entries(self, now):
2017-02-26 13:07:30 +01:00
"""Create fake history entries."""
# create 12 history items spaced 6 hours apart, starting from now
entry_count = 12
interval = 6 * 60 * 60
items = []
for i in range(entry_count):
entry_atime = now - i * interval
2017-02-26 13:07:30 +01:00
entry = history.Entry(atime=str(entry_atime),
url=QUrl("www.x.com/" + str(i)), title="Page " + str(i))
items.insert(0, entry)
return items
2017-02-08 09:28:04 +01:00
2017-02-09 18:27:32 +01:00
@pytest.fixture
def fake_web_history(self, fake_save_manager, tmpdir):
"""Create a fake web-history and register it into objreg."""
web_history = history.WebHistory(tmpdir.dirname, 'fake-history')
objreg.register('web-history', web_history)
yield web_history
objreg.delete('web-history')
@pytest.fixture(autouse=True)
def fake_history(self, fake_web_history, entries):
2017-02-26 13:07:30 +01:00
"""Create fake history."""
for item in entries:
fake_web_history._add_entry(item)
fake_web_history.save()
2017-02-26 13:07:30 +01:00
@pytest.mark.parametrize("start_time_offset, expected_item_count", [
2017-03-02 18:40:24 +01:00
(0, 4),
(24*60*60, 4),
(48*60*60, 4),
(72*60*60, 0)
2017-02-26 13:07:30 +01:00
])
def test_qutehistory_data(self, start_time_offset, expected_item_count,
now):
2017-02-26 13:07:30 +01:00
"""Ensure qute://history/data returns correct items."""
start_time = now - start_time_offset
2017-02-26 13:07:30 +01:00
url = QUrl("qute://history/data?start_time=" + str(start_time))
2017-02-08 09:28:04 +01:00
_mimetype, data = qutescheme.qute_history(url)
2017-02-26 13:07:30 +01:00
items = json.loads(data)
2017-03-02 18:40:24 +01:00
items = [item for item in items if 'time' in item] # skip 'next' item
2017-02-09 13:18:57 +01:00
2017-02-26 13:07:30 +01:00
assert len(items) == expected_item_count
2017-02-09 13:18:57 +01:00
# test times
2017-02-26 13:07:30 +01:00
end_time = start_time - 24*60*60
2017-03-02 18:40:24 +01:00
for item in items:
assert item['time'] <= start_time * 1000
assert item['time'] > end_time * 1000
2017-02-09 21:56:06 +01:00
@pytest.mark.parametrize("start_time_offset, next_time", [
(0, 24*60*60),
(24*60*60, 48*60*60),
(48*60*60, -1),
(72*60*60, -1)
])
def test_qutehistory_next(self, start_time_offset, next_time, now):
"""Ensure qute://history/data returns correct items."""
start_time = now - start_time_offset
url = QUrl("qute://history/data?start_time=" + str(start_time))
_mimetype, data = qutescheme.qute_history(url)
items = json.loads(data)
2017-03-02 18:40:24 +01:00
items = [item for item in items if 'next' in item] # 'next' items
assert len(items) == 1
if next_time == -1:
assert items[0]["next"] == -1
else:
assert items[0]["next"] == now - next_time
def test_qute_history_benchmark(self, fake_web_history, benchmark, now):
Fix qute_history benchmark. This benchmark was running very quickly due to an improper setup. The current history implementation expects that a newly inserted entry must be more recent than any existing entries and sorts according to this assumption. The benchmark test inserts increasingly older entries, breaking this invariant. When run in the benchmark, the qute://history/data implementation would see an entry older than the oldest time in the time window and would immediately return with a single "next" entry. This patch inserts data in an order that mantains history's invariant and adds a sanity-check at the end of the test. It does not check for the exact length as not all entries will be within the time window. The length will be some values <= 100000, the check just ensures that there is at least something more than a "next" entry. Before: ---------------------------------------------- benchmark: 1 tests ---------------------------------------------- Name (time in us) Min Max Mean StdDev Median IQR Outliers(*) Rounds Iterations ---------------------------------------------------------------------------------------------------------------- test_qute_history_benchmark 9.3050 21.9250 9.6143 0.2454 9.5880 0.1070 230;360 9930 1 ---------------------------------------------------------------------------------------------------------------- After: -------------------------------------------------- benchmark: 1 tests ------------------------------------------------- Name (time in ms) Min Max Mean StdDev Median IQR Outliers(*) Rounds Iterations ----------------------------------------------------------------------------------------------------------------------- test_qute_history_benchmark 220.7040 223.1900 221.7536 1.1070 221.1939 1.8803 1;0 5 1 -----------------------------------------------------------------------------------------------------------------------
2017-04-16 15:01:46 +02:00
# items must be earliest-first to ensure history is sorted properly
for t in range(100000, 0, -1): # one history per second
2017-02-09 21:56:06 +01:00
entry = history.Entry(
atime=str(now - t),
2017-02-26 13:07:30 +01:00
url=QUrl('www.x.com/{}'.format(t)),
title='x at {}'.format(t))
2017-02-09 21:56:06 +01:00
fake_web_history._add_entry(entry)
url = QUrl("qute://history/data?start_time={}".format(now))
Fix qute_history benchmark. This benchmark was running very quickly due to an improper setup. The current history implementation expects that a newly inserted entry must be more recent than any existing entries and sorts according to this assumption. The benchmark test inserts increasingly older entries, breaking this invariant. When run in the benchmark, the qute://history/data implementation would see an entry older than the oldest time in the time window and would immediately return with a single "next" entry. This patch inserts data in an order that mantains history's invariant and adds a sanity-check at the end of the test. It does not check for the exact length as not all entries will be within the time window. The length will be some values <= 100000, the check just ensures that there is at least something more than a "next" entry. Before: ---------------------------------------------- benchmark: 1 tests ---------------------------------------------- Name (time in us) Min Max Mean StdDev Median IQR Outliers(*) Rounds Iterations ---------------------------------------------------------------------------------------------------------------- test_qute_history_benchmark 9.3050 21.9250 9.6143 0.2454 9.5880 0.1070 230;360 9930 1 ---------------------------------------------------------------------------------------------------------------- After: -------------------------------------------------- benchmark: 1 tests ------------------------------------------------- Name (time in ms) Min Max Mean StdDev Median IQR Outliers(*) Rounds Iterations ----------------------------------------------------------------------------------------------------------------------- test_qute_history_benchmark 220.7040 223.1900 221.7536 1.1070 221.1939 1.8803 1;0 5 1 -----------------------------------------------------------------------------------------------------------------------
2017-04-16 15:01:46 +02:00
_mimetype, data = benchmark(qutescheme.qute_history, url)
assert len(json.loads(data)) > 1