test_uri.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # coding: utf-8
  2. # Copyright 2006-2009 Canonical Ltd. All rights reserved.
  3. #
  4. # This file is part of lazr.uri
  5. #
  6. # lazr.uri is free software: you can redistribute it and/or modify it
  7. # under the terms of the GNU Lesser General Public License as published by
  8. # the Free Software Foundation, version 3 of the License.
  9. #
  10. # lazr.uri is distributed in the hope that it will be useful, but WITHOUT
  11. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  13. # License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with lazr.uri. If not, see <http://www.gnu.org/licenses/>.
  17. """Unit tests."""
  18. __metaclass__ = type
  19. __all__ = [
  20. 'test_suite',
  21. ]
  22. from collections import defaultdict
  23. import unittest
  24. from lazr.uri import (
  25. InvalidURIError, URI, find_uris_in_text, merge, remove_dot_segments)
  26. class URITestCase(unittest.TestCase):
  27. def test_normalisation(self):
  28. # URI normalisation examples from Section 6.2.2 of RFC 3986.
  29. self.assertEqual(str(URI('eXAMPLE://a/./b/../b/%63/%7bfoo%7d')),
  30. 'example://a/b/c/%7Bfoo%7D')
  31. self.assertEqual(str(URI('http://www.EXAMPLE.com/')),
  32. 'http://www.example.com/')
  33. self.assertEqual(str(URI('http://www.gnome.org/%7ejamesh/')),
  34. 'http://www.gnome.org/~jamesh/')
  35. # Port number normalisation, and adding missing slash for URIs
  36. # with authority:
  37. self.assertEqual(str(URI('http://example.com')),
  38. 'http://example.com/')
  39. self.assertEqual(str(URI('http://example.com:/')),
  40. 'http://example.com/')
  41. self.assertEqual(str(URI('http://example.com:80/')),
  42. 'http://example.com/')
  43. def test_hashable(self):
  44. uri_groups = [
  45. ['eXAMPLE://a/./b/../b/%63/%7bfoo%7d',
  46. 'example://a/b/c/%7Bfoo%7D'],
  47. ['http://www.EXAMPLE.com/',
  48. 'http://www.example.com/'],
  49. ['http://www.gnome.org/%7ejamesh/',
  50. 'http://www.gnome.org/~jamesh/'],
  51. ['http://example.com',
  52. 'http://example.com/',
  53. 'http://example.com:/',
  54. 'http://example.com:80/'],
  55. ]
  56. uri_hashes = defaultdict(list)
  57. for uri_group in uri_groups:
  58. for uri in uri_group:
  59. uri_hashes[hash(URI(uri))].append(uri)
  60. self.assertEqual(len(uri_groups), len(uri_hashes))
  61. for uri_group in uri_groups:
  62. self.assertEqual(
  63. sorted(uri_group),
  64. sorted(uri_hashes[hash(URI(uri_group[0]))]))
  65. def test_invalid_uri(self):
  66. self.assertRaises(InvalidURIError, URI, 'http://€xample.com/')
  67. def test_merge(self):
  68. # Test that the merge() function performs as described in
  69. # Section 5.2.3 of RFC 3986
  70. self.assertEqual(merge('', 'foo', has_authority=True), '/foo')
  71. self.assertEqual(merge('', 'foo', has_authority=False), 'foo')
  72. self.assertEqual(merge('/a/b/c', 'foo', has_authority=True),
  73. '/a/b/foo')
  74. self.assertEqual(merge('/a/b/', 'foo', has_authority=True),
  75. '/a/b/foo')
  76. def test_remove_dot_segments(self):
  77. # remove_dot_segments() examples from Section 5.2.4 of RFC 3986:
  78. self.assertEqual(remove_dot_segments('/a/b/c/./../../g'), '/a/g')
  79. self.assertEqual(remove_dot_segments('mid/content=5/../6'), 'mid/6')
  80. def test_normal_resolution(self):
  81. # Normal URI resolution examples from Section 5.4.1 of RFC 3986:
  82. base = URI('http://a/b/c/d;p?q')
  83. def resolve(relative):
  84. return str(base.resolve(relative))
  85. self.assertEqual(resolve('g:h'), 'g:h')
  86. self.assertEqual(resolve('g'), 'http://a/b/c/g')
  87. self.assertEqual(resolve('./g'), 'http://a/b/c/g')
  88. self.assertEqual(resolve('g/'), 'http://a/b/c/g/')
  89. self.assertEqual(resolve('/g'), 'http://a/g')
  90. # The extra slash here comes from normalisation:
  91. self.assertEqual(resolve('//g'), 'http://g/')
  92. self.assertEqual(resolve('?y'), 'http://a/b/c/d;p?y')
  93. self.assertEqual(resolve('g?y'), 'http://a/b/c/g?y')
  94. self.assertEqual(resolve('#s'), 'http://a/b/c/d;p?q#s')
  95. self.assertEqual(resolve('g#s'), 'http://a/b/c/g#s')
  96. self.assertEqual(resolve('g?y#s'), 'http://a/b/c/g?y#s')
  97. self.assertEqual(resolve(';x'), 'http://a/b/c/;x')
  98. self.assertEqual(resolve('g;x'), 'http://a/b/c/g;x')
  99. self.assertEqual(resolve('g;x?y#s'), 'http://a/b/c/g;x?y#s')
  100. self.assertEqual(resolve(''), 'http://a/b/c/d;p?q')
  101. self.assertEqual(resolve('.'), 'http://a/b/c/')
  102. self.assertEqual(resolve('./'), 'http://a/b/c/')
  103. self.assertEqual(resolve('..'), 'http://a/b/')
  104. self.assertEqual(resolve('../'), 'http://a/b/')
  105. self.assertEqual(resolve('../g'), 'http://a/b/g')
  106. self.assertEqual(resolve('../..'), 'http://a/')
  107. self.assertEqual(resolve('../../'), 'http://a/')
  108. self.assertEqual(resolve('../../g'), 'http://a/g')
  109. def test_abnormal_resolution(self):
  110. # Abnormal URI resolution examples from Section 5.4.2 of RFC 3986:
  111. base = URI('http://a/b/c/d;p?q')
  112. def resolve(relative):
  113. return str(base.resolve(relative))
  114. self.assertEqual(resolve('../../../g'), 'http://a/g')
  115. self.assertEqual(resolve('../../../../g'),'http://a/g')
  116. self.assertEqual(resolve('/./g'), 'http://a/g')
  117. self.assertEqual(resolve('/../g'), 'http://a/g')
  118. self.assertEqual(resolve('g.'), 'http://a/b/c/g.')
  119. self.assertEqual(resolve('.g'), 'http://a/b/c/.g')
  120. self.assertEqual(resolve('g..'), 'http://a/b/c/g..')
  121. self.assertEqual(resolve('..g'), 'http://a/b/c/..g')
  122. self.assertEqual(resolve('./../g'), 'http://a/b/g')
  123. self.assertEqual(resolve('./g/.'), 'http://a/b/c/g/')
  124. self.assertEqual(resolve('g/./h'), 'http://a/b/c/g/h')
  125. self.assertEqual(resolve('g/../h'), 'http://a/b/c/h')
  126. self.assertEqual(resolve('g;x=1/./y'), 'http://a/b/c/g;x=1/y')
  127. self.assertEqual(resolve('g;x=1/../y'), 'http://a/b/c/y')
  128. self.assertEqual(resolve('g?y/./x'), 'http://a/b/c/g?y/./x')
  129. self.assertEqual(resolve('g?y/../x'), 'http://a/b/c/g?y/../x')
  130. self.assertEqual(resolve('g#s/./x'), 'http://a/b/c/g#s/./x')
  131. self.assertEqual(resolve('g#s/../x'), 'http://a/b/c/g#s/../x')
  132. # XXX 2009-01-30 jamesh:
  133. # I've disabled this test since we refuse to accept HTTP URIs
  134. # without a hostname component.
  135. #self.assertEqual(resolve('http:g'), 'http:g')
  136. def test_underDomain_matches_subdomain(self):
  137. # URI.underDomain should return True when asked whether the url is
  138. # under one of its parent domains.
  139. uri = URI('http://code.launchpad.dev/foo')
  140. self.assertTrue(uri.underDomain('code.launchpad.dev'))
  141. self.assertTrue(uri.underDomain('launchpad.dev'))
  142. self.assertTrue(uri.underDomain(''))
  143. def test_underDomain_doesnt_match_non_subdomain(self):
  144. # URI.underDomain should return False when asked whether the url is
  145. # under a domain which isn't one of its parents.
  146. uri = URI('http://code.launchpad.dev/foo')
  147. self.assertFalse(uri.underDomain('beta.code.launchpad.dev'))
  148. self.assertFalse(uri.underDomain('google.com'))
  149. self.assertFalse(uri.underDomain('unchpad.dev'))
  150. def additional_tests():
  151. return unittest.TestLoader().loadTestsFromName(__name__)