Hi,
At Sat, 19 May 2007 04:03:13 +0900,
Daniel Martin wrote in [ruby-talk:252151]:
I've converted all the test examples in that section of RFC 3986 into
test code; see below.
Thank you and sorry to be late.
And even with Nakada-san's patch, there's still a problem or two with
our resolver relative to the RFC 3986 test cases. However, with that
patch it passes everything labeled in the RFC as "Normal Cases"
(section 5.4.1). It still has issues with the abnormal cases of
section 5.4.2
URI.parse("ftp://example.com/pub").path returns "/pub" in 1.8
while "pub" in 1.9. Is 1.9 correct?
Index: lib/uri/generic.rb
===================================================================
--- lib/uri/generic.rb (revision 12858)
+++ lib/uri/generic.rb (working copy)
@@ -617,10 +617,6 @@ module URI
def merge_path(base, rel)
- # RFC2396, Section 5.2, 5)
- if rel[0] == ?/ #/
- # RFC2396, Section 5.2, 5)
- return rel
- else
+ # RFC2396, Section 5.2, 5)
# RFC2396, Section 5.2, 6)
base_path = split_path(base)
@@ -632,8 +628,8 @@ module URI
base_path.slice!(i - 1, 2)
end
- if base_path.empty?
- base_path = [''] # keep '/' for root directory
- else
- base_path.pop
+
+ if (first = rel_path.first) and first.empty?
+ base_path.clear
+ rel_path.shift
end
@@ -654,10 +650,15 @@ module URI
end
- add_trailer_slash = true
+ add_trailer_slash = !tmp.empty?
+ if base_path.empty?
+ base_path = [''] # keep '/' for root directory
+ elsif add_trailer_slash
+ base_path.pop
+ end
while x = tmp.shift
- if x == '..' && base_path.size > 1
+ if x == '..'
# RFC2396, Section 4
# a .. or . in an absolute path has no special meaning
- base_path.pop
+ base_path.pop if base_path.size > 1
else
# if x == '..'
@@ -676,5 +677,4 @@ module URI
return base_path.join('/')
end
- end
private :merge_path
Index: test/uri/test_generic.rb
===================================================================
--- test/uri/test_generic.rb (revision 12858)
+++ test/uri/test_generic.rb (working copy)
@@ -1,9 +1,7 @@
require 'test/unit'
require 'uri'
+require 'enumerator'
-module URI
-
-
-class TestGeneric < Test::Unit::TestCase
+class URI::TestGeneric < Test::Unit::TestCase
def setup
@url = '
http://a/b/c/d;p?q'
@@ -297,9 +295,9 @@ class TestGeneric < Test::Unit::TestCase
#
http://a/b/c/d;p?q
-# ?y =
http://a/b/c/?y
+# ?y =
http://a/b/c/d;p?y
url = @base_url.merge('?y')
assert_kind_of(URI::HTTP, url)
- assert_equal('
http://a/b/c/?y', url.to_s)
- url = @base_url.route_to('
http://a/b/c/?y')
+ assert_equal('
http://a/b/c/d;p?y', url.to_s)
+ url = @base_url.route_to('
http://a/b/c/d;p?y')
assert_kind_of(URI::Generic, url)
assert_equal('?y', url.to_s)
@@ -453,8 +451,8 @@ class TestGeneric < Test::Unit::TestCase
#
http://a/b/c/d;p?q
-# /./g =
http://a/./g
+# /./g =
http://a/g
url = @base_url.merge('/./g')
assert_kind_of(URI::HTTP, url)
- assert_equal('
http://a/./g', url.to_s)
+ assert_equal('
http://a/g', url.to_s)
url = @base_url.route_to('
http://a/./g')
assert_kind_of(URI::Generic, url)
@@ -465,5 +463,5 @@ class TestGeneric < Test::Unit::TestCase
url = @base_url.merge('/../g')
assert_kind_of(URI::HTTP, url)
- assert_equal('
http://a/../g', url.to_s)
+ assert_equal('
http://a/g', url.to_s)
url = @base_url.route_to('
http://a/../g')
assert_kind_of(URI::Generic, url)
@@ -507,8 +505,8 @@ class TestGeneric < Test::Unit::TestCase
#
http://a/b/c/d;p?q
-# ../../../g =
http://a/../g
+# ../../../g =
http://a/g
url = @base_url.merge('../../../g')
assert_kind_of(URI::HTTP, url)
- assert_equal('
http://a/../g', url.to_s)
+ assert_equal('
http://a/g', url.to_s)
url = @base_url.route_to('
http://a/../g')
assert_kind_of(URI::Generic, url)
@@ -520,5 +518,5 @@ class TestGeneric < Test::Unit::TestCase
url = @base_url.merge('../../../../g')
assert_kind_of(URI::HTTP, url)
- assert_equal('
http://a/../../g', url.to_s)
+ assert_equal('
http://a/g', url.to_s)
url = @base_url.route_to('
http://a/../../g')
assert_kind_of(URI::Generic, url)
@@ -693,6 +691,56 @@ class TestGeneric < Test::Unit::TestCase
assert_raises(URI::InvalidURIError) { uri.query = 'bar' }
end
+
+ def m(s)
+ @base_url.merge(s).to_s
end
+ def test_rfc3986_examples
+ assert_equal("g:h", m("g:h"))
+ assert_equal("
http://a/b/c/g", m("g"))
+ assert_equal("
http://a/b/c/g", m("./g"))
+ assert_equal("
http://a/b/c/g/", m("g/"))
+ assert_equal("
http://a/g", m("/g"))
+ assert_equal("
http://g", m("//g"))
+ assert_equal("
http://a/b/c/d;p?y", m("?y"))
+ assert_equal("
http://a/b/c/g?y", m("g?y"))
+ assert_equal("
http://a/b/c/d;p?q#s", m("#s"))
+ assert_equal("
http://a/b/c/g#s", m("g#s"))
+ assert_equal("
http://a/b/c/g?y#s", m("g?y#s"))
+ assert_equal("
http://a/b/c/;x", m(";x"))
+ assert_equal("
http://a/b/c/g;x", m("g;x"))
+ assert_equal("
http://a/b/c/g;x?y#s", m("g;x?y#s"))
+ assert_equal("
http://a/b/c/d;p?q", m(""))
+ assert_equal("
http://a/b/c/", m("."))
+ assert_equal("
http://a/b/c/", m("./"))
+ assert_equal("
http://a/b/", m(".."))
+ assert_equal("
http://a/b/", m("../"))
+ assert_equal("
http://a/b/g", m("../g"))
+ assert_equal("
http://a/", m("../.."))
+ assert_equal("
http://a/", m("../../"))
+ assert_equal("
http://a/g", m("../../g"))
+ assert_equal("
http://a/g", m("../../../g"))
+ assert_equal("
http://a/g", m("../../../../g"))
+
+ assert_equal("
http://a/g", m("/./g"))
+ assert_equal("
http://a/g", m("/../g"))
+ assert_equal("
http://a/b/c/g.", m("g."))
+ assert_equal("
http://a/b/c/.g", m(".g"))
+ assert_equal("
http://a/b/c/g..", m("g.."))
+ assert_equal("
http://a/b/c/..g", m("..g"))
+
+ assert_equal("
http://a/b/g", m("./../g"))
+ assert_equal("
http://a/b/c/g/", m("./g/."))
+ assert_equal("
http://a/b/c/g/h", m("g/./h"))
+ assert_equal("
http://a/b/c/h", m("g/../h"))
+ assert_equal("
http://a/b/c/g;x=1/y", m("g;x=1/./y"))
+ assert_equal("
http://a/b/c/y", m("g;x=1/../y"))
+
+ assert_equal("
http://a/b/c/g?y/./x", m("g?y/./x"))
+ assert_equal("
http://a/b/c/g?y/../x", m("g?y/../x"))
+ assert_equal("
http://a/b/c/g#s/./x", m("g#s/./x"))
+ assert_equal("
http://a/b/c/g#s/../x", m("g#s/../x"))
+ assert_equal("http:g", m("http:g"))
+ end
end