Fix Python3 bug and add tests
Tests are currently broken because refactoring
This commit is contained in:
1
dev-requirements.txt
Normal file
1
dev-requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
pytest
|
||||
@@ -1,15 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
# For details about delimiters, see:
|
||||
important_characters = {
|
||||
'generic_delimiters': ":/?#[]@",
|
||||
'sub_delimiters': "!$&'()*+,;=",
|
||||
'unreserved_chars': ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
'012345789._~-')
|
||||
}
|
||||
# For details about delimiters and reserved characters, see:
|
||||
# http://tools.ietf.org/html/rfc3986#section-2.2
|
||||
GENERIC_DELIMITERS = set((":", "/", "?", "#", "[", "]", "@"))
|
||||
SUB_DELIMITERS = set(("!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="))
|
||||
GENERIC_DELIMITERS = set(important_characters['generic_delimiters'])
|
||||
SUB_DELIMITERS = set(important_characters['sub_delimiters'])
|
||||
RESERVED_CHARS = GENERIC_DELIMITERS.union(SUB_DELIMITERS)
|
||||
UNRESERVED_CHARS = set(
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
'0123456789-._~'
|
||||
)
|
||||
# For details about unreserved characters, see:
|
||||
# http://tools.ietf.org/html/rfc3986#section-2.3
|
||||
UNRESERVED_CHARS = set(important_characters['unreserved_chars'])
|
||||
|
||||
# Extracted from http://tools.ietf.org/html/rfc3986#appendix-B
|
||||
pattern_dict = {
|
||||
@@ -58,8 +63,10 @@ variations = [
|
||||
|
||||
ipv6 = '(({0})|({1})|({2})|({3})|({4})|({5})|({6})|({7}))'.format(*variations)
|
||||
|
||||
ipv_future = 'v[0-9A-Fa-f]{1}.[%s]{1}' % (
|
||||
''.join(UNRESERVED_CHARS.union(SUB_DELIMITERS).union(':')))
|
||||
ipv_future = 'v[0-9A-Fa-f]+.[%s]+' % (
|
||||
'A-Za-z0-9._~\-' + # We need to escape the '-' in this case
|
||||
"!$&'()\*+,;=" + # We need to escape the '*' in this case
|
||||
':')
|
||||
|
||||
ip_literal = '\[({0}|{1})\]'.format(ipv6, ipv_future)
|
||||
|
||||
@@ -67,10 +74,10 @@ ip_literal = '\[({0}|{1})\]'.format(ipv6, ipv_future)
|
||||
HOST_PATTERN = '({0}|{1}|{2})'.format(reg_name, ipv4, ip_literal)
|
||||
|
||||
SUBAUTHORITY_MATCHER = re.compile((
|
||||
'^(?:(?P<userinfo>[{0}%:]+)@)?' # userinfo
|
||||
'(?P<host>{1}?)' # host
|
||||
'^(?:(?P<userinfo>[A-Za-z0-9_.~\-%:]+)@)?' # userinfo
|
||||
'(?P<host>{0}?)' # host
|
||||
':?(?P<port>\d+)?$' # port
|
||||
).format(''.join(UNRESERVED_CHARS), HOST_PATTERN))
|
||||
).format(HOST_PATTERN))
|
||||
|
||||
# These are enumerated for the named tuple used as a superclass of
|
||||
# URIReference
|
||||
|
||||
4
tests/conftest.py
Normal file
4
tests/conftest.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, '.')
|
||||
166
tests/test_uri.py
Normal file
166
tests/test_uri.py
Normal file
@@ -0,0 +1,166 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
|
||||
from rfc3986.exceptions import InvalidAuthority
|
||||
from rfc3986.uri import URIReference
|
||||
|
||||
|
||||
# ##########
|
||||
# IPv6 Tests
|
||||
# ##########
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def basic_uri(request):
|
||||
return 'http://%s' % request.param
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def basic_uri_with_port(request):
|
||||
return 'ftp://%s:21' % request.param
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def uri_with_port_and_userinfo(request):
|
||||
return 'ssh://user:pass@%s:22' % request.param
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def basic_uri_with_path(request):
|
||||
return 'http://%s/path/to/resource' % request.param
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def uri_with_path_and_query(request):
|
||||
return 'http://%s/path/to/resource?key=value' % request.param
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def uri_with_everything(request):
|
||||
return 'https://user:pass@%s:443/path/to/resource?key=value#fragment' % (
|
||||
request.param)
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
'[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '::1', '127.0.0.1',
|
||||
'www.example.com',
|
||||
])
|
||||
def relative_uri():
|
||||
return '//[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def invalid_ipv6():
|
||||
return 'https://[FADF:01]'
|
||||
|
||||
|
||||
class TestURIReferenceParsesURIs:
|
||||
"""Tests for URIReference handling of IPv6 URIs."""
|
||||
def test_handles_basic_uri(self, basic_uri):
|
||||
"""Test that URIReference can handle a simple IPv6 URI."""
|
||||
uri = URIReference.from_string(basic_uri)
|
||||
assert uri.scheme == 'http'
|
||||
assert uri.authority == basic_uri[7:] # len('http://')
|
||||
assert uri.host == uri.authority
|
||||
assert uri.path == ''
|
||||
assert uri.query is None
|
||||
assert uri.fragment is None
|
||||
assert uri.port is None
|
||||
assert uri.userinfo is None
|
||||
|
||||
def test_handles_basic_ipv6_with_port(self, basic_ipv6_with_port):
|
||||
"""Test that URIReference can handle a simple IPv6 URI with a port."""
|
||||
uri = URIReference.from_string(basic_ipv6_with_port)
|
||||
assert uri.scheme == 'ftp'
|
||||
assert uri.authority == basic_ipv6_with_port[6:] # len('ftp://')
|
||||
assert uri.host != uri.authority
|
||||
assert uri.port == '21'
|
||||
assert uri.path == ''
|
||||
assert uri.query is None
|
||||
assert uri.fragment is None
|
||||
assert uri.userinfo is None
|
||||
|
||||
def test_handles_ipv6_with_port_and_userinfo(
|
||||
self, ipv6_with_port_and_userinfo):
|
||||
"""
|
||||
Test that URIReference can handle a IPv6 URI with a port and userinfo.
|
||||
"""
|
||||
uri = URIReference.from_string(ipv6_with_port_and_userinfo)
|
||||
assert uri.scheme == 'ssh'
|
||||
# 6 == len('ftp://')
|
||||
assert uri.authority == ipv6_with_port_and_userinfo[6:]
|
||||
assert uri.host != uri.authority
|
||||
assert uri.port == '22'
|
||||
assert uri.path == ''
|
||||
assert uri.query is None
|
||||
assert uri.fragment is None
|
||||
assert uri.userinfo == 'user:pass'
|
||||
|
||||
def test_handles_basic_ipv6_with_path(self, basic_ipv6_with_path):
|
||||
"""Test that URIReference can handle a IPv6 URI with a path."""
|
||||
uri = URIReference.from_string(basic_ipv6_with_path)
|
||||
assert uri.scheme == 'http'
|
||||
assert basic_ipv6_with_path == (uri.scheme + '://' + uri.authority
|
||||
+ uri.path)
|
||||
assert uri.host == uri.authority
|
||||
assert uri.path == '/path/to/resource'
|
||||
assert uri.query is None
|
||||
assert uri.fragment is None
|
||||
assert uri.userinfo is None
|
||||
assert uri.port is None
|
||||
|
||||
def test_handles_ipv6_with_path_and_query(self, ipv6_with_path_and_query):
|
||||
"""
|
||||
Test that URIReference can handle a IPv6 URI with a path and query.
|
||||
"""
|
||||
uri = URIReference.from_string(ipv6_with_path_and_query)
|
||||
assert uri.scheme == 'http'
|
||||
assert uri.host == uri.authority
|
||||
assert uri.path == '/path/to/resource'
|
||||
assert uri.query == 'key=value'
|
||||
assert uri.fragment is None
|
||||
assert uri.userinfo is None
|
||||
assert uri.port is None
|
||||
|
||||
def test_handles_ipv6_with_everything(self, ipv6_with_everything):
|
||||
"""
|
||||
Test that URIReference can handle and IPv6 with everything in it.
|
||||
"""
|
||||
uri = URIReference.from_string(ipv6_with_everything)
|
||||
assert uri.scheme == 'https'
|
||||
assert uri.host == '[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]'
|
||||
assert uri.path == '/path/to/resource'
|
||||
assert uri.query == 'key=value'
|
||||
assert uri.fragment == 'fragment'
|
||||
assert uri.userinfo == 'user:pass'
|
||||
assert uri.port == '443'
|
||||
|
||||
def test_authority_info_raises_InvalidAuthority(self, invalid_ipv6):
|
||||
"""Test that an invalid IPv6 is caught by authority_info()."""
|
||||
uri = URIReference.from_string(invalid_ipv6)
|
||||
with pytest.raises(InvalidAuthority):
|
||||
uri.authority_info()
|
||||
|
||||
def test_handles_relative_ipv6(self, relative_ipv6):
|
||||
"""Test that URIReference can handle a relative IPv6 URI."""
|
||||
uri = URIReference.from_string(relative_ipv6)
|
||||
assert uri.scheme is None
|
||||
assert uri.authority == relative_ipv6[2:]
|
||||
Reference in New Issue
Block a user