Move logic from _navigate_incdec to urlutils
Also add unittests for url_incdec_number
This commit is contained in:
parent
0f3aa0bd8c
commit
276b163e0d
@ -19,7 +19,6 @@
|
||||
|
||||
"""Command dispatcher for TabbedBrowser."""
|
||||
|
||||
import re
|
||||
import os
|
||||
import shlex
|
||||
import posixpath
|
||||
@ -472,31 +471,10 @@ class CommandDispatcher:
|
||||
background: Open the link in a new background tab.
|
||||
window: Open the link in a new window.
|
||||
"""
|
||||
path = url.path()
|
||||
# Get the last number in a string
|
||||
match = re.match(r'(.*\D|^)(\d+)(.*)', path)
|
||||
if not match:
|
||||
raise cmdexc.CommandError("No number found in URL!")
|
||||
pre, number, post = match.groups()
|
||||
if not number:
|
||||
raise cmdexc.CommandError("No number found in URL!")
|
||||
try:
|
||||
val = int(number)
|
||||
except ValueError:
|
||||
raise cmdexc.CommandError("Could not parse number '{}'.".format(
|
||||
number))
|
||||
if incdec == 'decrement':
|
||||
if val <= 0:
|
||||
raise cmdexc.CommandError("Can't decrement {}!".format(val))
|
||||
val -= 1
|
||||
elif incdec == 'increment':
|
||||
val += 1
|
||||
else:
|
||||
raise ValueError("Invalid value {} for indec!".format(incdec))
|
||||
new_path = ''.join([pre, str(val), post])
|
||||
# Make a copy of the QUrl so we don't modify the original
|
||||
new_url = QUrl(url)
|
||||
new_url.setPath(new_path)
|
||||
new_url = urlutils.url_incdec_number(url, incdec)
|
||||
except urlutils.IncDecError as error:
|
||||
raise cmdexc.CommandError(error.msg)
|
||||
self._open(new_url, tab, background, window)
|
||||
|
||||
def _navigate_up(self, url, tab, background, window):
|
||||
|
@ -443,3 +443,60 @@ class FuzzyUrlError(Exception):
|
||||
return self.msg
|
||||
else:
|
||||
return '{}: {}'.format(self.msg, self.url.errorString())
|
||||
|
||||
|
||||
class IncDecError(Exception):
|
||||
|
||||
"""Exception raised by url_incdec_number on problems.
|
||||
|
||||
Attributes:
|
||||
msg: The error message.
|
||||
url: The QUrl which caused the error.
|
||||
"""
|
||||
|
||||
def __init__(self, msg, url):
|
||||
super().__init__(msg)
|
||||
self.url = url
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return '{}: {}'.format(self.msg, self.url.toString())
|
||||
|
||||
|
||||
def url_incdec_number(url, incdec):
|
||||
"""Find a number in the url and increment or decrement it.
|
||||
|
||||
Args:
|
||||
url: The current url
|
||||
incdec: Either 'increment' or 'decrement'
|
||||
|
||||
Return:
|
||||
The new url with the number incremented/decremented.
|
||||
|
||||
Raises IncDecError if the url contains no number.
|
||||
"""
|
||||
path = url.path()
|
||||
# Get the last number in a string
|
||||
match = re.match(r'(.*\D|^)(\d+)(.*)', path)
|
||||
if not match:
|
||||
raise IncDecError("No number found in URL!", url)
|
||||
pre, number, post = match.groups()
|
||||
if not number:
|
||||
raise IncDecError("No number found in URL!", url)
|
||||
try:
|
||||
val = int(number)
|
||||
except ValueError:
|
||||
raise IncDecError("Could not parse number '{}'.".format(number), url)
|
||||
if incdec == 'decrement':
|
||||
if val <= 0:
|
||||
raise IncDecError("Can't decrement {}!".format(val), url)
|
||||
val -= 1
|
||||
elif incdec == 'increment':
|
||||
val += 1
|
||||
else:
|
||||
raise ValueError("Invalid value {} for indec!".format(incdec))
|
||||
new_path = ''.join([pre, str(val), post])
|
||||
# Make a copy of the QUrl so we don't modify the original
|
||||
new_url = QUrl(url)
|
||||
new_url.setPath(new_path)
|
||||
return new_url
|
||||
|
@ -524,3 +524,39 @@ def test_same_domain_invalid_url(url1, url2):
|
||||
"""Test same_domain with invalid URLs."""
|
||||
with pytest.raises(ValueError):
|
||||
urlutils.same_domain(QUrl(url1), QUrl(url2))
|
||||
|
||||
@pytest.mark.parametrize('url, incdec, output', [
|
||||
("http://example.com/index1.html", "increment", "http://example.com/index2.html"),
|
||||
("http://foo.bar/folder_1/image_2", "increment", "http://foo.bar/folder_1/image_3"),
|
||||
("http://bbc.c0.uk:80/story_1", "increment", "http://bbc.c0.uk:80/story_2"),
|
||||
("http://mydomain.tld/1_%C3%A4", "increment", "http://mydomain.tld/2_%C3%A4"),
|
||||
|
||||
("http://example.com/index10.html", "decrement", "http://example.com/index9.html"),
|
||||
("http://foo.bar/folder_1/image_3", "decrement", "http://foo.bar/folder_1/image_2"),
|
||||
("http://bbc.c0.uk:80/story_1", "decrement", "http://bbc.c0.uk:80/story_0"),
|
||||
("http://mydomain.tld/2_%C3%A4", "decrement", "http://mydomain.tld/1_%C3%A4"),
|
||||
])
|
||||
def test_url_incdec_number(url, incdec, output):
|
||||
"""Test url_incdec_number with valid URLs."""
|
||||
new_url = urlutils.url_incdec_number(QUrl(url), incdec)
|
||||
assert new_url == QUrl(output)
|
||||
|
||||
@pytest.mark.parametrize('url', [
|
||||
"http://example.com/long/path/but/no/number",
|
||||
"http://ex4mple.com/number/in/hostname",
|
||||
"http://example.com:42/number/in/port",
|
||||
"http://www2.example.com/number/in/subdomain",
|
||||
"http://example.com/%C3%B6/urlencoded/data",
|
||||
"http://www2.ex4mple.com:42/all/of/the/%C3%A4bove",
|
||||
])
|
||||
def test_url_incdec_number_invalid(url):
|
||||
"""Test url_incdec_number with URLs that don't contain a number."""
|
||||
with pytest.raises(urlutils.IncDecError):
|
||||
urlutils.url_incdec_number(QUrl(url), "increment")
|
||||
|
||||
def test_url_incdec_number_below_0():
|
||||
"""Test url_incdec_number with a number that would be below zero
|
||||
after decrementing."""
|
||||
with pytest.raises(urlutils.IncDecError):
|
||||
urlutils.url_incdec_number(QUrl('http://example.com/page_0.html'),
|
||||
'decrement')
|
||||
|
Loading…
Reference in New Issue
Block a user