Handle explicit searches with auto-search=false.

See #497.
This commit is contained in:
Florian Bruhin 2015-02-02 22:19:43 +01:00
parent cbde36948a
commit a95dda8e92
2 changed files with 75 additions and 31 deletions

View File

@ -29,13 +29,19 @@ from qutebrowser.utils import urlutils
from qutebrowser.test import stubs from qutebrowser.test import stubs
CONFIG = { def get_config_stub(auto_search=True):
'general': {'auto-search': True}, """Get a config stub.
'searchengines': {
'test': 'http://www.qutebrowser.org/?q={}', Args:
'DEFAULT': 'http://www.example.com/?q={}', auto_search: The value auto-search should have.
}, """
} return {
'general': {'auto-search': auto_search},
'searchengines': {
'test': 'http://www.qutebrowser.org/?q={}',
'DEFAULT': 'http://www.example.com/?q={}',
},
}
class SpecialURLTests(unittest.TestCase): class SpecialURLTests(unittest.TestCase):
@ -83,7 +89,7 @@ class SearchUrlTests(unittest.TestCase):
def setUp(self): def setUp(self):
self.config = urlutils.config self.config = urlutils.config
urlutils.config = stubs.ConfigStub(CONFIG) urlutils.config = stubs.ConfigStub(get_config_stub())
def test_default_engine(self): def test_default_engine(self):
"""Test default search engine.""" """Test default search engine."""
@ -125,7 +131,6 @@ class SearchUrlTests(unittest.TestCase):
urlutils.config = self.config urlutils.config = self.config
@unittest.mock.patch('qutebrowser.utils.urlutils.config.get', autospec=True)
class IsUrlTests(unittest.TestCase): class IsUrlTests(unittest.TestCase):
"""Tests for is_url. """Tests for is_url.
@ -133,6 +138,9 @@ class IsUrlTests(unittest.TestCase):
Class attributes: Class attributes:
URLS: A list of strings which are URLs. URLS: A list of strings which are URLs.
NOT_URLS: A list of strings which aren't URLs. NOT_URLS: A list of strings which aren't URLs.
Attributes:
config: The urlutils.config instance.
""" """
URLS = ( URLS = (
@ -160,20 +168,36 @@ class IsUrlTests(unittest.TestCase):
'http:foo:0', 'http:foo:0',
) )
def test_urls(self, configmock): def setUp(self):
self.config = urlutils.config
def test_urls(self):
"""Test things which are URLs.""" """Test things which are URLs."""
configmock.return_value = 'naive' urlutils.config = stubs.ConfigStub(get_config_stub('naive'))
for url in self.URLS: for url in self.URLS:
with self.subTest(url=url): with self.subTest(url=url):
self.assertTrue(urlutils.is_url(url), url) self.assertTrue(urlutils.is_url(url), url)
def test_not_urls(self, configmock): def test_not_urls(self):
"""Test things which are not URLs.""" """Test things which are not URLs."""
configmock.return_value = 'naive' urlutils.config = stubs.ConfigStub(get_config_stub('naive'))
for url in self.NOT_URLS: for url in self.NOT_URLS:
with self.subTest(url=url): with self.subTest(url=url):
self.assertFalse(urlutils.is_url(url), url) self.assertFalse(urlutils.is_url(url), url)
def test_search_autosearch(self):
"""Test explicit search with auto-search=True"""
urlutils.config = stubs.ConfigStub(get_config_stub(True))
self.assertFalse(urlutils.is_url('test foo'))
def test_search_no_autosearch(self):
"""Test explicit search with auto-search=False"""
urlutils.config = stubs.ConfigStub(get_config_stub(False))
self.assertFalse(urlutils.is_url('test foo'))
def tearDown(self):
urlutils.config = self.config
class QurlFromUserInputTests(unittest.TestCase): class QurlFromUserInputTests(unittest.TestCase):

View File

@ -37,6 +37,32 @@ from qutebrowser.commands import cmdexc
# https://github.com/The-Compiler/qutebrowser/issues/108 # https://github.com/The-Compiler/qutebrowser/issues/108
def _parse_search_term(s):
"""Get a search engine name and search term from a string.
Args:
s: The string to get a search engine for.
Return:
A (engine, term) tuple, where engine is None for the default engine.
"""
m = re.search(r'(^\w+)\s+(.+)($|\s+)', s)
if m:
engine = m.group(1)
try:
config.get('searchengines', engine)
except configexc.NoOptionError:
engine = None
term = s
else:
term = m.group(2).rstrip()
else:
engine = None
term = s
log.url.debug("engine {}, term '{}'".format(engine, term))
return (engine, term)
def _get_search_url(txt): def _get_search_url(txt):
"""Get a search engine URL for a text. """Get a search engine URL for a text.
@ -47,24 +73,13 @@ def _get_search_url(txt):
The search URL as a QUrl. The search URL as a QUrl.
""" """
log.url.debug("Finding search engine for '{}'".format(txt)) log.url.debug("Finding search engine for '{}'".format(txt))
r = re.compile(r'(^\w+)\s+(.+)($|\s+)') engine, term = _parse_search_term(txt)
m = r.search(txt)
if m:
engine = m.group(1)
try:
template = config.get('searchengines', engine)
except configexc.NoOptionError:
template = config.get('searchengines', 'DEFAULT')
term = txt
else:
term = m.group(2).rstrip()
log.url.debug("engine {}, term '{}'".format(engine, term))
else:
template = config.get('searchengines', 'DEFAULT')
term = txt
log.url.debug("engine: default, term '{}'".format(txt))
if not term: if not term:
raise FuzzyUrlError("No search term given") raise FuzzyUrlError("No search term given")
if engine is None:
template = config.get('searchengines', 'DEFAULT')
else:
template = config.get('searchengines', engine)
url = qurl_from_user_input(template.format(urllib.parse.quote(term))) url = qurl_from_user_input(template.format(urllib.parse.quote(term)))
qtutils.ensure_valid(url) qtutils.ensure_valid(url)
return url return url
@ -206,8 +221,13 @@ def is_url(urlstr):
qurl = QUrl(urlstr) qurl = QUrl(urlstr)
if not autosearch: if not autosearch:
# no autosearch, so everything is a URL. # no autosearch, so everything is a URL unless it has an explicit
return True # search engine.
engine, _term = _parse_search_term(urlstr)
if engine is None:
return True
else:
return False
if _has_explicit_scheme(qurl): if _has_explicit_scheme(qurl):
# URLs with explicit schemes are always URLs # URLs with explicit schemes are always URLs