Add/improve tests for qutebrowser.utils.urlutils.
This commit is contained in:
parent
e3fcc0e091
commit
3f13c2bd3e
@ -266,7 +266,7 @@ def is_url(urlstr):
|
|||||||
elif autosearch == 'naive':
|
elif autosearch == 'naive':
|
||||||
log.url.debug("Checking via naive check")
|
log.url.debug("Checking via naive check")
|
||||||
url = _is_url_naive(urlstr)
|
url = _is_url_naive(urlstr)
|
||||||
else:
|
else: # pragma: no cover
|
||||||
raise ValueError("Invalid autosearch value")
|
raise ValueError("Invalid autosearch value")
|
||||||
log.url.debug("url = {}".format(url))
|
log.url.debug("url = {}".format(url))
|
||||||
return url
|
return url
|
||||||
|
@ -28,7 +28,7 @@ import pytest
|
|||||||
|
|
||||||
import stubs as stubsmod
|
import stubs as stubsmod
|
||||||
from qutebrowser.config import configexc
|
from qutebrowser.config import configexc
|
||||||
from qutebrowser.utils import objreg
|
from qutebrowser.utils import objreg, usertypes
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session', autouse=True)
|
@pytest.fixture(scope='session', autouse=True)
|
||||||
@ -217,3 +217,58 @@ def pytest_runtest_setup(item):
|
|||||||
pytest.skip("Can't be run when frozen!")
|
pytest.skip("Can't be run when frozen!")
|
||||||
elif item.get_marker('frozen') and not getattr(sys, 'frozen', False):
|
elif item.get_marker('frozen') and not getattr(sys, 'frozen', False):
|
||||||
pytest.skip("Can only run when frozen!")
|
pytest.skip("Can only run when frozen!")
|
||||||
|
|
||||||
|
|
||||||
|
class MessageMock:
|
||||||
|
|
||||||
|
"""Helper object for message_mock.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
_monkeypatch: The pytest monkeypatch fixture.
|
||||||
|
MessageLevel: An enum with possible message levels.
|
||||||
|
Message: A namedtuple representing a message.
|
||||||
|
messages: A list of Message tuples.
|
||||||
|
"""
|
||||||
|
|
||||||
|
Message = collections.namedtuple('Message', ['level', 'win_id', 'text',
|
||||||
|
'immediate'])
|
||||||
|
MessageLevel = usertypes.enum('Level', ('error', 'info', 'warning'))
|
||||||
|
|
||||||
|
def __init__(self, monkeypatch):
|
||||||
|
self._monkeypatch = monkeypatch
|
||||||
|
self.messages = []
|
||||||
|
|
||||||
|
def _handle(self, level, win_id, text, immediately=False):
|
||||||
|
self.messages.append(self.Message(level, win_id, text, immediately))
|
||||||
|
|
||||||
|
def _handle_error(self, *args, **kwargs):
|
||||||
|
self._handle(self.MessageLevel.error, *args, **kwargs)
|
||||||
|
|
||||||
|
def _handle_info(self, *args, **kwargs):
|
||||||
|
self._handle(self.MessageLevel.info, *args, **kwargs)
|
||||||
|
|
||||||
|
def _handle_warning(self, *args, **kwargs):
|
||||||
|
self._handle(self.MessageLevel.warning, *args, **kwargs)
|
||||||
|
|
||||||
|
def getmsg(self):
|
||||||
|
"""Get the only message in self.messages.
|
||||||
|
|
||||||
|
Raises ValueError if there are multiple or no messages.
|
||||||
|
"""
|
||||||
|
if len(self.messages) != 1:
|
||||||
|
raise ValueError("Got {} messages but expected a single "
|
||||||
|
"one.".format(len(self.messages)))
|
||||||
|
return self.messages[0]
|
||||||
|
|
||||||
|
def patch(self, module_path):
|
||||||
|
"""Patch message.* in the given module (as a string)."""
|
||||||
|
self._monkeypatch.setattr(module_path + '.error', self._handle_error)
|
||||||
|
self._monkeypatch.setattr(module_path + '.info', self._handle_info)
|
||||||
|
self._monkeypatch.setattr(module_path + '.warning',
|
||||||
|
self._handle_warning)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def message_mock(monkeypatch):
|
||||||
|
"""Fixture to get a MessageMock."""
|
||||||
|
return MessageMock(monkeypatch)
|
||||||
|
@ -21,209 +21,478 @@
|
|||||||
|
|
||||||
"""Tests for qutebrowser.utils.urlutils."""
|
"""Tests for qutebrowser.utils.urlutils."""
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
import collections
|
||||||
|
|
||||||
from PyQt5.QtCore import QUrl
|
from PyQt5.QtCore import QUrl
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from qutebrowser.utils import urlutils
|
from qutebrowser.commands import cmdexc
|
||||||
|
from qutebrowser.utils import utils, urlutils, qtutils
|
||||||
|
|
||||||
|
|
||||||
def init_config_stub(stub, auto_search=True):
|
class FakeDNS:
|
||||||
|
|
||||||
|
"""Helper class for the fake_dns fixture.
|
||||||
|
|
||||||
|
Class attributes:
|
||||||
|
FakeDNSAnswer: Helper class/namedtuple imitating a QHostInfo object
|
||||||
|
(used by fromname_mock).
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
used: Whether the fake DNS server was used since it was
|
||||||
|
created/reseted.
|
||||||
|
answer: What to return for the given host(True/False). Needs to be set
|
||||||
|
when fromname_mock is called.
|
||||||
|
"""
|
||||||
|
|
||||||
|
FakeDNSAnswer = collections.namedtuple('FakeDNSAnswer', ['error'])
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return utils.get_repr(self, used=self.used, answer=self.answer)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""Reset used/answer as if the FakeDNS was freshly created."""
|
||||||
|
self.used = False
|
||||||
|
self.answer = None
|
||||||
|
|
||||||
|
def _get_error(self):
|
||||||
|
return not self.answer
|
||||||
|
|
||||||
|
def fromname_mock(self, _host):
|
||||||
|
"""Simple mock for QHostInfo::fromName returning a FakeDNSAnswer."""
|
||||||
|
if self.answer is None:
|
||||||
|
raise ValueError("Got called without answer being set. This means "
|
||||||
|
"something tried to make an unexpected DNS "
|
||||||
|
"request (QHostInfo::fromName).")
|
||||||
|
if self.used:
|
||||||
|
raise ValueError("Got used twice!.")
|
||||||
|
self.used = True
|
||||||
|
return self.FakeDNSAnswer(error=self._get_error)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def fake_dns(monkeypatch):
|
||||||
|
"""Patched QHostInfo.fromName to catch DNS requests.
|
||||||
|
|
||||||
|
With autouse=True so accidental DNS requests get discovered because the
|
||||||
|
fromname_mock will be called without answer being set.
|
||||||
|
"""
|
||||||
|
dns = FakeDNS()
|
||||||
|
monkeypatch.setattr('qutebrowser.utils.urlutils.QHostInfo.fromName',
|
||||||
|
dns.fromname_mock)
|
||||||
|
return dns
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def urlutils_config_stub(config_stub, monkeypatch):
|
||||||
"""Initialize the given config_stub.
|
"""Initialize the given config_stub.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
stub: The ConfigStub provided by the config_stub fixture.
|
stub: The ConfigStub provided by the config_stub fixture.
|
||||||
auto_search: The value auto-search should have.
|
auto_search: The value auto-search should have.
|
||||||
"""
|
"""
|
||||||
stub.data = {
|
config_stub.data = {
|
||||||
'general': {'auto-search': auto_search},
|
'general': {'auto-search': True},
|
||||||
'searchengines': {
|
'searchengines': {
|
||||||
'test': 'http://www.qutebrowser.org/?q={}',
|
'test': 'http://www.qutebrowser.org/?q={}',
|
||||||
'DEFAULT': 'http://www.example.com/?q={}',
|
'DEFAULT': 'http://www.example.com/?q={}',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
monkeypatch.setattr('qutebrowser.utils.urlutils.config', config_stub)
|
||||||
|
return config_stub
|
||||||
|
|
||||||
|
|
||||||
class TestSpecialURL:
|
@pytest.fixture
|
||||||
|
def urlutils_message_mock(message_mock):
|
||||||
|
"""Customized message_mock for the urlutils module."""
|
||||||
|
message_mock.patch('qutebrowser.utils.urlutils.message')
|
||||||
|
return message_mock
|
||||||
|
|
||||||
"""Test is_special_url.
|
|
||||||
|
|
||||||
Attributes:
|
class TestFuzzyUrl:
|
||||||
SPECIAL_URLS: URLs which are special.
|
|
||||||
NORMAL_URLS: URLs which are not special.
|
"""Tests for urlutils.fuzzy_url()."""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def os_mock(self, mocker):
|
||||||
|
"""Mock the os module and some os.path functions."""
|
||||||
|
m = mocker.patch('qutebrowser.utils.urlutils.os')
|
||||||
|
# Using / to get the same behavior across OS'
|
||||||
|
m.path.join.side_effect = lambda *args: '/'.join(args)
|
||||||
|
m.path.expanduser.side_effect = os.path.expanduser
|
||||||
|
return m
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def is_url_mock(self, mocker):
|
||||||
|
return mocker.patch('qutebrowser.utils.urlutils.is_url')
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def get_search_url_mock(self, mocker):
|
||||||
|
return mocker.patch('qutebrowser.utils.urlutils._get_search_url')
|
||||||
|
|
||||||
|
def test_file_relative_cwd(self, os_mock):
|
||||||
|
"""Test with relative=True, cwd set, and an existing file."""
|
||||||
|
os_mock.path.exists.return_value = True
|
||||||
|
os_mock.path.isabs.return_value = False
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo', cwd='cwd', relative=True)
|
||||||
|
|
||||||
|
os_mock.path.exists.assert_called_once_with('cwd/foo')
|
||||||
|
assert url == QUrl('file:cwd/foo')
|
||||||
|
|
||||||
|
def test_file_relative(self, os_mock):
|
||||||
|
"""Test with relative=True and cwd unset."""
|
||||||
|
os_mock.path.exists.return_value = True
|
||||||
|
os_mock.path.abspath.return_value = 'abs_path'
|
||||||
|
os_mock.path.isabs.return_value = False
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo', relative=True)
|
||||||
|
|
||||||
|
os_mock.path.exists.assert_called_once_with('abs_path')
|
||||||
|
assert url == QUrl('file:abs_path')
|
||||||
|
|
||||||
|
def test_file_relative_os_error(self, os_mock, is_url_mock):
|
||||||
|
"""Test with relative=True, cwd unset and abspath raising OSError."""
|
||||||
|
os_mock.path.abspath.side_effect = OSError
|
||||||
|
os_mock.path.exists.return_value = True
|
||||||
|
os_mock.path.isabs.return_value = False
|
||||||
|
is_url_mock.return_value = True
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo', relative=True)
|
||||||
|
assert not os_mock.path.exists.called
|
||||||
|
assert url == QUrl('http://foo')
|
||||||
|
|
||||||
|
def test_file_absolute(self, os_mock):
|
||||||
|
"""Test with an absolute path."""
|
||||||
|
os_mock.path.exists.return_value = True
|
||||||
|
os_mock.path.isabs.return_value = True
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('/foo')
|
||||||
|
assert url == QUrl('file:///foo')
|
||||||
|
|
||||||
|
def test_file_absolute_expanded(self, os_mock):
|
||||||
|
"""Make sure ~ gets expanded correctly."""
|
||||||
|
os_mock.path.exists.return_value = True
|
||||||
|
os_mock.path.isabs.return_value = True
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('~/foo')
|
||||||
|
assert url == QUrl('file://' + os.path.expanduser('~/foo'))
|
||||||
|
|
||||||
|
def test_address(self, os_mock, is_url_mock):
|
||||||
|
"""Test passing something with relative=False."""
|
||||||
|
os_mock.path.isabs.return_value = False
|
||||||
|
is_url_mock.return_value = True
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo')
|
||||||
|
assert url == QUrl('http://foo')
|
||||||
|
|
||||||
|
def test_search_term(self, os_mock, is_url_mock, get_search_url_mock):
|
||||||
|
"""Test passing something with do_search=True."""
|
||||||
|
os_mock.path.isabs.return_value = False
|
||||||
|
is_url_mock.return_value = False
|
||||||
|
get_search_url_mock.return_value = QUrl('search_url')
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo', do_search=True)
|
||||||
|
assert url == QUrl('search_url')
|
||||||
|
|
||||||
|
def test_search_term_value_error(self, os_mock, is_url_mock,
|
||||||
|
get_search_url_mock):
|
||||||
|
"""Test with do_search=True and ValueError in _get_search_url."""
|
||||||
|
os_mock.path.isabs.return_value = False
|
||||||
|
is_url_mock.return_value = False
|
||||||
|
get_search_url_mock.side_effect = ValueError
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo', do_search=True)
|
||||||
|
assert url == QUrl('http://foo')
|
||||||
|
|
||||||
|
def test_no_do_search(self, is_url_mock):
|
||||||
|
"""Test with do_search = False."""
|
||||||
|
is_url_mock.return_value = False
|
||||||
|
|
||||||
|
url = urlutils.fuzzy_url('foo', do_search=False)
|
||||||
|
assert url == QUrl('http://foo')
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('do_search, exception', [
|
||||||
|
(True, qtutils.QtValueError),
|
||||||
|
(False, urlutils.FuzzyUrlError),
|
||||||
|
])
|
||||||
|
def test_invalid_url(self, do_search, exception, is_url_mock, monkeypatch):
|
||||||
|
"""Test with an invalid URL."""
|
||||||
|
is_url_mock.return_value = True
|
||||||
|
monkeypatch.setattr('qutebrowser.utils.urlutils.qurl_from_user_input',
|
||||||
|
lambda url: QUrl())
|
||||||
|
with pytest.raises(exception):
|
||||||
|
urlutils.fuzzy_url('foo', do_search=do_search)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url, special', [
|
||||||
|
('file:///tmp/foo', True),
|
||||||
|
('about:blank', True),
|
||||||
|
('qute:version', True),
|
||||||
|
('http://www.qutebrowser.org/', False),
|
||||||
|
('www.qutebrowser.org', False),
|
||||||
|
])
|
||||||
|
def test_special_urls(url, special):
|
||||||
|
assert urlutils.is_special_url(QUrl(url)) == special
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url, host, query', [
|
||||||
|
('testfoo', 'www.example.com', 'q=testfoo'),
|
||||||
|
('test testfoo', 'www.qutebrowser.org', 'q=testfoo'),
|
||||||
|
('test testfoo bar foo', 'www.qutebrowser.org', 'q=testfoo bar foo'),
|
||||||
|
('test testfoo ', 'www.qutebrowser.org', 'q=testfoo'),
|
||||||
|
('!python testfoo', 'www.example.com', 'q=%21python testfoo'),
|
||||||
|
('blub testfoo', 'www.example.com', 'q=blub testfoo'),
|
||||||
|
])
|
||||||
|
def test_get_search_url(urlutils_config_stub, url, host, query):
|
||||||
|
"""Test _get_search_url().
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The "URL" to enter.
|
||||||
|
host: The expected search machine host.
|
||||||
|
query: The expected search query.
|
||||||
"""
|
"""
|
||||||
|
url = urlutils._get_search_url(url)
|
||||||
SPECIAL_URLS = (
|
assert url.host() == host
|
||||||
'file:///tmp/foo',
|
assert url.query() == query
|
||||||
'about:blank',
|
|
||||||
'qute:version'
|
|
||||||
)
|
|
||||||
|
|
||||||
NORMAL_URLS = (
|
|
||||||
'http://www.qutebrowser.org/',
|
|
||||||
'www.qutebrowser.org'
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('url', SPECIAL_URLS)
|
|
||||||
def test_special_urls(self, url):
|
|
||||||
"""Test special URLs."""
|
|
||||||
u = QUrl(url)
|
|
||||||
assert urlutils.is_special_url(u)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('url', NORMAL_URLS)
|
|
||||||
def test_normal_urls(self, url):
|
|
||||||
"""Test non-special URLs."""
|
|
||||||
u = QUrl(url)
|
|
||||||
assert not urlutils.is_special_url(u)
|
|
||||||
|
|
||||||
|
|
||||||
class TestSearchUrl:
|
@pytest.mark.parametrize('is_url, is_url_no_autosearch, uses_dns, url', [
|
||||||
|
# Normal hosts
|
||||||
|
(True, True, False, 'http://foobar'),
|
||||||
|
(True, True, False, 'localhost:8080'),
|
||||||
|
(True, True, True, 'qutebrowser.org'),
|
||||||
|
(True, True, True, ' qutebrowser.org '),
|
||||||
|
(True, True, False, 'http://user:password@example.com/foo?bar=baz#fish'),
|
||||||
|
# IPs
|
||||||
|
(True, True, False, '127.0.0.1'),
|
||||||
|
(True, True, False, '::1'),
|
||||||
|
(True, True, True, '2001:41d0:2:6c11::1'),
|
||||||
|
(True, True, True, '94.23.233.17'),
|
||||||
|
# Special URLs
|
||||||
|
(True, True, False, 'file:///tmp/foo'),
|
||||||
|
(True, True, False, 'about:blank'),
|
||||||
|
(True, True, False, 'qute:version'),
|
||||||
|
(True, True, False, 'localhost'),
|
||||||
|
# _has_explicit_scheme False, special_url True
|
||||||
|
(True, True, False, 'qute::foo'),
|
||||||
|
# Invalid URLs
|
||||||
|
(False, True, False, ''),
|
||||||
|
(False, True, False, 'http:foo:0'),
|
||||||
|
# Not URLs
|
||||||
|
(False, True, False, 'foo bar'), # no DNS because of space
|
||||||
|
(False, True, False, 'localhost test'), # no DNS because of space
|
||||||
|
(False, True, False, 'another . test'), # no DNS because of space
|
||||||
|
(False, True, True, 'foo'),
|
||||||
|
(False, True, False, 'this is: not an URL'), # no DNS because of space
|
||||||
|
(False, True, False, '23.42'), # no DNS because bogus-IP
|
||||||
|
(False, True, False, '1337'), # no DNS because bogus-IP
|
||||||
|
(False, True, True, 'deadbeef'),
|
||||||
|
(False, True, False, '31c3'), # no DNS because bogus-IP
|
||||||
|
(False, True, False, 'foo::bar'), # no DNS because of no host
|
||||||
|
# Valid search term with autosearch
|
||||||
|
(False, False, False, 'test foo'),
|
||||||
|
# autosearch = False
|
||||||
|
(False, True, False, 'This is an URL without autosearch'),
|
||||||
|
])
|
||||||
|
def test_is_url(urlutils_config_stub, fake_dns, is_url, is_url_no_autosearch,
|
||||||
|
uses_dns, url):
|
||||||
|
"""Test is_url().
|
||||||
|
|
||||||
"""Test _get_search_url."""
|
Args:
|
||||||
|
is_url: Whether the given string is an URL with auto-search dns/naive.
|
||||||
@pytest.fixture(autouse=True)
|
is_url_no_autosearch: Whether the given string is an URL with
|
||||||
def mock_config(self, config_stub, monkeypatch):
|
auto-search false.
|
||||||
"""Fixture to patch urlutils.config with a stub."""
|
uses_dns: Whether the given string should fire a DNS request for the
|
||||||
init_config_stub(config_stub)
|
given URL.
|
||||||
monkeypatch.setattr('qutebrowser.utils.urlutils.config', config_stub)
|
url: The URL to test, as a string.
|
||||||
|
|
||||||
def test_default_engine(self):
|
|
||||||
"""Test default search engine."""
|
|
||||||
url = urlutils._get_search_url('testfoo')
|
|
||||||
assert url.host() == 'www.example.com'
|
|
||||||
assert url.query() == 'q=testfoo'
|
|
||||||
|
|
||||||
def test_engine_pre(self):
|
|
||||||
"""Test search engine name with one word."""
|
|
||||||
url = urlutils._get_search_url('test testfoo')
|
|
||||||
assert url.host() == 'www.qutebrowser.org'
|
|
||||||
assert url.query() == 'q=testfoo'
|
|
||||||
|
|
||||||
def test_engine_pre_multiple_words(self):
|
|
||||||
"""Test search engine name with multiple words."""
|
|
||||||
url = urlutils._get_search_url('test testfoo bar foo')
|
|
||||||
assert url.host() == 'www.qutebrowser.org'
|
|
||||||
assert url.query() == 'q=testfoo bar foo'
|
|
||||||
|
|
||||||
def test_engine_pre_whitespace_at_end(self):
|
|
||||||
"""Test search engine name with one word and whitespace."""
|
|
||||||
url = urlutils._get_search_url('test testfoo ')
|
|
||||||
assert url.host() == 'www.qutebrowser.org'
|
|
||||||
assert url.query() == 'q=testfoo'
|
|
||||||
|
|
||||||
def test_engine_with_bang_pre(self):
|
|
||||||
"""Test search engine with a prepended !bang."""
|
|
||||||
url = urlutils._get_search_url('!python testfoo')
|
|
||||||
assert url.host() == 'www.example.com'
|
|
||||||
assert url.query() == 'q=%21python testfoo'
|
|
||||||
|
|
||||||
def test_engine_wrong(self):
|
|
||||||
"""Test with wrong search engine."""
|
|
||||||
url = urlutils._get_search_url('blub testfoo')
|
|
||||||
assert url.host() == 'www.example.com'
|
|
||||||
assert url.query() == 'q=blub testfoo'
|
|
||||||
|
|
||||||
|
|
||||||
class TestIsUrl:
|
|
||||||
|
|
||||||
"""Tests for is_url.
|
|
||||||
|
|
||||||
Class attributes:
|
|
||||||
URLS: A list of strings which are URLs.
|
|
||||||
NOT_URLS: A list of strings which aren't URLs.
|
|
||||||
"""
|
"""
|
||||||
|
urlutils_config_stub.data['general']['auto-search'] = 'dns'
|
||||||
|
if uses_dns:
|
||||||
|
fake_dns.answer = True
|
||||||
|
result = urlutils.is_url(url)
|
||||||
|
assert fake_dns.used
|
||||||
|
assert result
|
||||||
|
fake_dns.reset()
|
||||||
|
|
||||||
URLS = (
|
fake_dns.answer = False
|
||||||
'http://foobar',
|
result = urlutils.is_url(url)
|
||||||
'localhost:8080',
|
assert fake_dns.used
|
||||||
'qutebrowser.org',
|
assert not result
|
||||||
' qutebrowser.org ',
|
else:
|
||||||
'127.0.0.1',
|
result = urlutils.is_url(url)
|
||||||
'::1',
|
assert not fake_dns.used
|
||||||
'2001:41d0:2:6c11::1',
|
assert result == is_url
|
||||||
'94.23.233.17',
|
|
||||||
'http://user:password@qutebrowser.org/foo?bar=baz#fish',
|
|
||||||
)
|
|
||||||
|
|
||||||
NOT_URLS = (
|
fake_dns.reset()
|
||||||
'foo bar',
|
urlutils_config_stub.data['general']['auto-search'] = 'naive'
|
||||||
'localhost test',
|
assert urlutils.is_url(url) == is_url
|
||||||
'another . test',
|
assert not fake_dns.used
|
||||||
'foo',
|
|
||||||
'this is: not an URL',
|
|
||||||
'23.42',
|
|
||||||
'1337',
|
|
||||||
'deadbeef',
|
|
||||||
'31c3',
|
|
||||||
'http:foo:0',
|
|
||||||
'foo::bar',
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('url', URLS)
|
fake_dns.reset()
|
||||||
def test_urls(self, monkeypatch, config_stub, url):
|
urlutils_config_stub.data['general']['auto-search'] = False
|
||||||
"""Test things which are URLs."""
|
assert urlutils.is_url(url) == is_url_no_autosearch
|
||||||
init_config_stub(config_stub, 'naive')
|
assert not fake_dns.used
|
||||||
monkeypatch.setattr('qutebrowser.utils.urlutils.config', config_stub)
|
|
||||||
assert urlutils.is_url(url), url
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('url', NOT_URLS)
|
|
||||||
def test_not_urls(self, monkeypatch, config_stub, url):
|
|
||||||
"""Test things which are not URLs."""
|
|
||||||
init_config_stub(config_stub, 'naive')
|
|
||||||
monkeypatch.setattr('qutebrowser.utils.urlutils.config', config_stub)
|
|
||||||
assert not urlutils.is_url(url), url
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('autosearch', [True, False])
|
|
||||||
def test_search_autosearch(self, monkeypatch, config_stub, autosearch):
|
|
||||||
"""Test explicit search with auto-search=True."""
|
|
||||||
init_config_stub(config_stub, autosearch)
|
|
||||||
monkeypatch.setattr('qutebrowser.utils.urlutils.config', config_stub)
|
|
||||||
assert not urlutils.is_url('test foo')
|
|
||||||
|
|
||||||
|
|
||||||
class TestQurlFromUserInput:
|
@pytest.mark.parametrize('user_input, output', [
|
||||||
|
('qutebrowser.org', 'http://qutebrowser.org'),
|
||||||
|
('http://qutebrowser.org', 'http://qutebrowser.org'),
|
||||||
|
('::1/foo', 'http://[::1]/foo'),
|
||||||
|
('[::1]/foo', 'http://[::1]/foo'),
|
||||||
|
('http://[::1]', 'http://[::1]'),
|
||||||
|
('qutebrowser.org', 'http://qutebrowser.org'),
|
||||||
|
('http://qutebrowser.org', 'http://qutebrowser.org'),
|
||||||
|
('::1/foo', 'http://[::1]/foo'),
|
||||||
|
('[::1]/foo', 'http://[::1]/foo'),
|
||||||
|
('http://[::1]', 'http://[::1]'),
|
||||||
|
])
|
||||||
|
def test_qurl_from_user_input(user_input, output):
|
||||||
|
"""Test qurl_from_user_input.
|
||||||
|
|
||||||
"""Tests for qurl_from_user_input."""
|
Args:
|
||||||
|
user_input: The string to pass to qurl_from_user_input.
|
||||||
def test_url(self):
|
output: The expected QUrl string.
|
||||||
"""Test a normal URL."""
|
"""
|
||||||
url = urlutils.qurl_from_user_input('qutebrowser.org')
|
url = urlutils.qurl_from_user_input(user_input)
|
||||||
assert url.toString() == 'http://qutebrowser.org'
|
assert url.toString() == output
|
||||||
|
|
||||||
def test_url_http(self):
|
|
||||||
"""Test a normal URL with http://."""
|
|
||||||
url = urlutils.qurl_from_user_input('http://qutebrowser.org')
|
|
||||||
assert url.toString() == 'http://qutebrowser.org'
|
|
||||||
|
|
||||||
def test_ipv6_bare(self):
|
|
||||||
"""Test an IPv6 without brackets."""
|
|
||||||
url = urlutils.qurl_from_user_input('::1/foo')
|
|
||||||
assert url.toString() == 'http://[::1]/foo'
|
|
||||||
|
|
||||||
def test_ipv6(self):
|
|
||||||
"""Test an IPv6 with brackets."""
|
|
||||||
url = urlutils.qurl_from_user_input('[::1]/foo')
|
|
||||||
assert url.toString() == 'http://[::1]/foo'
|
|
||||||
|
|
||||||
def test_ipv6_http(self):
|
|
||||||
"""Test an IPv6 with http:// and brackets."""
|
|
||||||
url = urlutils.qurl_from_user_input('http://[::1]')
|
|
||||||
assert url.toString() == 'http://[::1]'
|
|
||||||
|
|
||||||
|
|
||||||
class TestFilenameFromUrl:
|
@pytest.mark.parametrize('url, valid, has_err_string', [
|
||||||
|
('http://www.example.com/', True, False),
|
||||||
|
('', False, False),
|
||||||
|
('://', False, True),
|
||||||
|
])
|
||||||
|
def test_invalid_url_error(urlutils_message_mock, url, valid, has_err_string):
|
||||||
|
"""Test invalid_url_error().
|
||||||
|
|
||||||
"""Tests for filename_from_url."""
|
Args:
|
||||||
|
url: The URL to check.
|
||||||
|
valid: Whether the QUrl is valid (isValid() == True).
|
||||||
|
has_err_string: Whether the QUrl is expected to have errorString set.
|
||||||
|
"""
|
||||||
|
qurl = QUrl(url)
|
||||||
|
assert qurl.isValid() == valid
|
||||||
|
if valid:
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
urlutils.invalid_url_error(0, qurl, '')
|
||||||
|
assert not urlutils_message_mock.messages
|
||||||
|
else:
|
||||||
|
assert bool(qurl.errorString()) == has_err_string
|
||||||
|
urlutils.invalid_url_error(0, qurl, 'frozzle')
|
||||||
|
|
||||||
def test_invalid_url(self):
|
msg = urlutils_message_mock.getmsg()
|
||||||
"""Test with an invalid QUrl."""
|
assert msg.win_id == 0
|
||||||
assert urlutils.filename_from_url(QUrl()) is None
|
assert not msg.immediate
|
||||||
|
if has_err_string:
|
||||||
|
expected_text = ("Trying to frozzle with invalid URL - " +
|
||||||
|
qurl.errorString())
|
||||||
|
else:
|
||||||
|
expected_text = "Trying to frozzle with invalid URL"
|
||||||
|
assert msg.text == expected_text
|
||||||
|
|
||||||
def test_url_path(self):
|
|
||||||
"""Test with an URL with path."""
|
|
||||||
url = QUrl('http://qutebrowser.org/test.html')
|
|
||||||
assert urlutils.filename_from_url(url) == 'test.html'
|
|
||||||
|
|
||||||
def test_url_host(self):
|
@pytest.mark.parametrize('url, valid, has_err_string', [
|
||||||
"""Test with an URL with no path."""
|
('http://www.example.com/', True, False),
|
||||||
url = QUrl('http://qutebrowser.org/')
|
('', False, False),
|
||||||
assert urlutils.filename_from_url(url) == 'qutebrowser.org.html'
|
('://', False, True),
|
||||||
|
])
|
||||||
|
def test_raise_cmdexc_if_invalid(url, valid, has_err_string):
|
||||||
|
"""Test raise_cmdexc_if_invalid.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL to check.
|
||||||
|
valid: Whether the QUrl is valid (isValid() == True).
|
||||||
|
has_err_string: Whether the QUrl is expected to have errorString set.
|
||||||
|
"""
|
||||||
|
qurl = QUrl(url)
|
||||||
|
assert qurl.isValid() == valid
|
||||||
|
if valid:
|
||||||
|
urlutils.raise_cmdexc_if_invalid(qurl)
|
||||||
|
else:
|
||||||
|
assert bool(qurl.errorString()) == has_err_string
|
||||||
|
with pytest.raises(cmdexc.CommandError) as excinfo:
|
||||||
|
urlutils.raise_cmdexc_if_invalid(qurl)
|
||||||
|
if has_err_string:
|
||||||
|
expected_text = "Invalid URL - " + qurl.errorString()
|
||||||
|
else:
|
||||||
|
expected_text = "Invalid URL"
|
||||||
|
assert str(excinfo.value) == expected_text
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('qurl, output', [
|
||||||
|
(QUrl(), None),
|
||||||
|
(QUrl('http://qutebrowser.org/test.html'), 'test.html'),
|
||||||
|
(QUrl('http://qutebrowser.org/foo.html#bar'), 'foo.html'),
|
||||||
|
(QUrl('http://user:password@qutebrowser.org/foo?bar=baz#fish'), 'foo'),
|
||||||
|
(QUrl('http://qutebrowser.org/'), 'qutebrowser.org.html'),
|
||||||
|
(QUrl('qute://'), None),
|
||||||
|
])
|
||||||
|
def test_filename_from_url(qurl, output):
|
||||||
|
assert urlutils.filename_from_url(qurl) == output
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('qurl, tpl', [
|
||||||
|
(QUrl(), None),
|
||||||
|
(QUrl('qute://'), None),
|
||||||
|
(QUrl('qute://foobar'), None),
|
||||||
|
(QUrl('mailto:nobody'), None),
|
||||||
|
(QUrl('ftp://example.com/'),
|
||||||
|
('ftp', 'example.com', 21)),
|
||||||
|
(QUrl('ftp://example.com:2121/'),
|
||||||
|
('ftp', 'example.com', 2121)),
|
||||||
|
(QUrl('http://qutebrowser.org:8010/waterfall'),
|
||||||
|
('http', 'qutebrowser.org', 8010)),
|
||||||
|
(QUrl('https://example.com/'),
|
||||||
|
('https', 'example.com', 443)),
|
||||||
|
(QUrl('https://example.com:4343/'),
|
||||||
|
('https', 'example.com', 4343)),
|
||||||
|
(QUrl('http://user:password@qutebrowser.org/foo?bar=baz#fish'),
|
||||||
|
('http', 'qutebrowser.org', 80)),
|
||||||
|
])
|
||||||
|
def test_host_tuple(qurl, tpl):
|
||||||
|
"""Test host_tuple().
|
||||||
|
|
||||||
|
Args:
|
||||||
|
qurl: The QUrl to pass.
|
||||||
|
tpl: The expected tuple, or None if a ValueError is expected.
|
||||||
|
"""
|
||||||
|
if tpl is None:
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
urlutils.host_tuple(qurl)
|
||||||
|
else:
|
||||||
|
assert urlutils.host_tuple(qurl) == tpl
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url, raising, has_err_string', [
|
||||||
|
(None, False, False),
|
||||||
|
(QUrl(), False, False),
|
||||||
|
(QUrl('http://www.example.com/'), True, False),
|
||||||
|
(QUrl('://'), False, True),
|
||||||
|
])
|
||||||
|
def test_fuzzy_url_error(url, raising, has_err_string):
|
||||||
|
"""Test FuzzyUrlError.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The URL to pass to FuzzyUrlError.
|
||||||
|
raising; True if the FuzzyUrlError should raise itself.
|
||||||
|
has_err_string: Whether the QUrl is expected to have errorString set.
|
||||||
|
"""
|
||||||
|
if raising:
|
||||||
|
expected_exc = ValueError
|
||||||
|
else:
|
||||||
|
expected_exc = urlutils.FuzzyUrlError
|
||||||
|
|
||||||
|
with pytest.raises(expected_exc) as excinfo:
|
||||||
|
raise urlutils.FuzzyUrlError("Error message", url)
|
||||||
|
|
||||||
|
if not raising:
|
||||||
|
if has_err_string:
|
||||||
|
expected_text = "Error message: " + url.errorString()
|
||||||
|
else:
|
||||||
|
expected_text = "Error message"
|
||||||
|
assert str(excinfo.value) == expected_text
|
||||||
|
Loading…
Reference in New Issue
Block a user