Fix Python3 bug and add tests

Tests are currently broken because refactoring
This commit is contained in:
Ian Cordasco
2014-06-24 19:13:40 -05:00
parent 96427281aa
commit ad6208e63f
4 changed files with 190 additions and 12 deletions

1
dev-requirements.txt Normal file
View File

@@ -0,0 +1 @@
pytest

View File

@@ -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
View File

@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
import sys
sys.path.insert(0, '.')

166
tests/test_uri.py Normal file
View 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:]